3 回答

TA贡献1848条经验 获得超10个赞
当外循环的第一次迭代完成内循环时,cvsReader
将达到 EOF,因此任何进一步的调用csvReader.readNext()
都将返回 null。
一种解决方案是不嵌套循环,而是首先将其中一个文件读入数组或其他集合,然后在读取第二个数组时对该数组进行处理。

TA贡献1876条经验 获得超5个赞
内部 while 循环将继续读取记录,csvReader直到没有要读取的记录为止。
csvReader不会因为 while 循环结束而“重置”:阅读器已完成。因此,下次您尝试从中读取记录时,它会立即返回;csvReader是仍然在最后。
要解决这个问题,您必须以某种方式重置csvReader回开始。大多数流样式的 Java API 故意不支持reset(因为许多数据源没有“请重新开始”的概念)。因此,要“重置”它,您必须在外循环内重新创建它,从而保证csvReader 每次循环时都有一个全新的。
如果您的源材料是文件,这可能会很慢。如果是网络连接,这是不可能的。但是,还有另一种解决方案:您可以从csvReader一遍读取记录并将它们保存在内存中,然后通过您的内存副本进行。如果源非常大(您需要大量 RAM),这是不可行的,但假设它不是:
// Save all records in csvReader into a list.
List<String[]> allRecords = new ArrayList<>();
while ((String[] record = csvReader.readNext()) != null) allRecords.add(record);
然后在您的内部循环中使用此列表:
while ((nextPM = csvReader2.readNext()) != null) {
System.out.println(nextPM[0]);
for (String[] nextRecord : allRecords) {
System.out.println(nextRecord[0] + "asd");
if(nextRecord[0].equals(nextPM[0])) {
System.out.println(nextRecord[0] + " " + nextRecord[1] + " " + nextPM[2]);
}
}
}

TA贡献1802条经验 获得超5个赞
您可以将csvReaderin的声明和初始化移动到内部循环开始上方的第一个 while 循环中。这样做可以为内循环的每次迭代创建一个新的读取器:
while ((nextPM = csvReader2.readNext()) != null) {
System.out.println(nextPM[0]);
CSVReader csvReader = new CSVReader(new FileReader("yourfile.csv"));
while ((nextRecord = csvReader.readNext()) != null) {
System.out.println(nextRecord[0] + "asd");
if(nextRecord[0].equals(nextPM[0])) {
System.out.println(nextRecord[0] + " " + nextRecord[1] + " " + nextPM[2]);
}
}
}
添加回答
举报