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

Cor*_*e7s 4 java csv parsing javabeans

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

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

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

    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 
                }
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*rad 6

进一步查看API 文档,我发现它CsvToBean<T>实现Iterable<T>并有一个iterator()返回 的方法,Iterator<T>记录如下:

此方法返回的迭代器一次接受一行输入并一次返回一个 bean。

所以看起来你可以将循环写为:

for (MyCustomClass myCustomClass : csvToBean) {
    // . . . do something with the bean . . .
}
Run Code Online (Sandbox Code Playgroud)

为了消除一些潜在的混乱,您可以在源代码中看到, 的build()方法CsvToBeanBuilder只是创建CsvToBean对象,并不执行实际的输入,而对象的parse()方法和迭代器CsvToBean都执行输入。