Почему CSVParser читает следующую CSVRecord
С помощью org.apache.commons.csv.CSVParser
У меня странное поведение.
Я пытаюсь прочитать, строка за строкой, CSV-файл, разделенный ;
но мой парсер пропускает строку по неизвестной причине.
Вот мой код:
public static void main(String[] args) {
try (
File file = new File("myFile.csv");
Reader reader = new BufferedReader(new FileReader(file));
CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT.withDelimiter(';'));
) {
if (!parser.iterator().hasNext()) {
throw new RuntimeException("The file is empty.");
}
while(parser.hasNext()) { //<----- This skip a line!
console.log(parser.iterator().next().get(0).trim());
}
}
}
Итак, моя консоль выглядит так:
line2
line4
line6
line8
line10
line12
так далее...
Поэтому моя проблема в том, что CSVParser пропускает строку parser.hasNext()
и это не должно
Мой код неверен? Я вполне уверен, что если я заменю парсер на ArrayList, то итератор будет работать, как и ожидалось... Это известная ошибка? Если да, можете ли вы, ребята, указать на обходной путь или лучшую библиотеку?
2 ответа
Проблема в том, что каждая итерация вызывает iterator()
, который возвращает NEW Iterator
,
После этого все становится странно, поскольку итератор current
поле, в котором хранится текущая запись, и, конечно, текущая запись нового итератора null
,
В таком случае это вызывает getNextRecord()
из CSVParser ( исходный код), таким образом пропуская строку.
Если вы хотите придерживаться итератора, просто используйте тот же экземпляр:
Iterator<CSVRecord> iterator = parser.iterator();
while(iterator.hasNext()) {
console.log(iterator.next().get(0).trim());
}
По умолчанию парсер считает первую строку заголовком (определение столбца), поэтому он пропускается в возвращаемых записях. Чтобы включить эту строку, вы должны соответствующим образом подготовить форматирование, используя withSkipHeaderRecord.
РЕДАКТИРОВАТЬ: Извините, я слишком быстро прочитал. Я думал, что только первая строка была пропущена.