在 java 中逐行解析整个 csv 文件

Parsing entire csv file vs parsing line by line in java

我有一个更大的 csv 文件,大约 80K 到 120K 行(取决于日期)。我成功地 运行 使用 @CsvBindByName 注释将整个 csv 文件解析为 java object 的代码。示例代码:

Reader reader = Files.newBufferedReader(Paths.get(file));
    CsvToBean csvToBean = new CsvToBeanBuilder<Object>(reader)
            .withType(MyCustomClass.class)
            .withIgnoreLeadingWhiteSpace(true)
            .build(); 
    List<MyCustomClass> myCustomClass= csvToBean.parse();`

我想更改此代码以逐行解析 csv 文件而不是整个文件,但保留映射到 java bean object 的整洁性。本质上是这样的:

    CSVReader csvReader = new CSVReader(Files.newBufferedReader(Paths.get(csvFileLoc)));
    String[] headerRow = csvReader.readNext(); // save the headerRow
    String [] nextLine = null;
    MyCustomClass myCustomClass = new MyCustomClass(); 
    while ((nextLine = csvReader.readNext())!=null) {
                    myCustomClass.setField1(nextLine[0]);
                    myCustomClass.setField2(nextLine[1]);
                    //.... so on 
                }

但是上述解决方案将我与了解每个字段的列位置联系起来。我想要的是基于 header 行映射我从 csv 获得的字符串数组,类似于 opencsv 在解析整个 csv 文件时所做的。但是,据我所知,我无法使用 opencsv 做到这一点。我原以为这是一种很常见的做法,但我无法在网上找到对此的任何参考。可能是我没有正确理解 opencsv 库的 CsvToBean 用法。我可以使用 csvToBean.iterator 遍历 bean,但我认为整个 csv 文件是使用 build 方法加载到内存中的,这违背了逐行读取的目的。欢迎提出任何建议

进一步查看 API docs,我看到 CsvToBean<T> 实现了 Iterable<T> 并且有一个 iterator() 方法 returns 和 Iterator<T>记录如下:

The iterator returned by this method takes one line of input at a time and returns one bean at a time.

所以看起来你可以把你的循环写成:

for (MyCustomClass myCustomClass : csvToBean) {
    // . . . do something with the bean . . .
}

为了消除一些潜在的混淆,您可以在源代码中看到 CsvToBean 对象的 build() method of CsvToBeanBuilder just creates the CsvToBean object, and doesn't do the actual input, and that the parse() method and the iterator 每个都执行输入。