Java CSVParser 读取后变空

Java CSVParser gets empty after reading it

在下面的代码片段中,我尝试使用 Apache Commons 库中的 CSVParser 读取 excel 文件。问题是为什么 records.getRecords(); 使 records 的列表为空。我应该如何注意这种行为?

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class ReadCSV {

    public ReadCSV() {
    }

    /* Define headers as enum */
    enum HEADER {
        ID, NAME, AGE
    }

    public List<List<String>> ReadCSVToList(String csvPath) throws IOException, HighBalanceException {
        List<List<String>> csvList = new ArrayList<>();
        try {


            Reader reader = new FileReader(csvPath);
            CSVParser  records = CSVFormat.DEFAULT.withHeader(HEADER.class).parse(reader);
            List<CSVRecord> records1 = records.getRecords();
            System.out.println(records1.size()); // 2
            List<CSVRecord> records2 = records.getRecords();
            System.out.println(records2.size()); // 0

如您在官方文档中所见:CSVParser#getRecords

The returned content starts at the current parse-position in the stream.

在您第一次调用getRecords时,解析位置在流的开头。第二次调用时,已经到流尾了。

一般来说,我总是建议您从文档开始。通常,只需少量阅读就可以轻松回答此类问题。如果还有不明白的地方,社区当然很乐意进一步帮助你。

阅读CSVParser的文档很有帮助:

Parses CSV files according to the specified format. [...] The parser works record wise. It is not possible to go back, once a record has been parsed from the input stream.

几段之后,在“解析到内存”标题下:

If parsing record wise is not desired, the contents of the input can be read completely into memory.

Reader in = new StringReader("a;b\nc;d");
CSVParser parser = new CSVParser(in, CSVFormat.EXCEL);
List<CSVRecord> list = parser.getRecords();

There are two constraints that have to be kept in mind:

  1. Parsing into memory starts at the current position of the parser. If you have already parsed records from the input, those records will not end up in the in memory representation of your CSV data.
  2. Parsing into memory may consume a lot of system resources depending on the input. For example if you're parsing a 150MB file of CSV data the contents will be read completely into memory.

当您第一次调用 records.getRecords() 时,您正在将 CSV 文件完全读入内存。再加上“从解析器的当前位置开始解析到内存中”这一事实意味着对于第二次调用,没有更多的记录要解析(因为解析器已经完全读取了文件。)