Java CSVParser读取后变空

Moh*_*mad -2 java apache-commons-csv

在下面的代码片段中,我尝试使用 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
Run Code Online (Sandbox Code Playgroud)

Tho*_*ger 6

它有助于阅读以下文档CSVParser

根据指定的格式解析CSV文件。[...]解析器按记录方式工作。一旦从输入流中解析了记录,就无法返回。

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

如果不需要按记录进行解析,则可以将输入的内容完全读入内存。

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

必须牢记两个限制:

  1. 解析到内存中从解析器的当前位置开始。如果您已经解析了输入中的记录,这些记录将不会最终出现在 CSV 数据的内存表示中。
  2. 根据输入的不同,解析到内存中可能会消耗大量系统资源。例如,如果您正在解析 150MB 的 CSV 数据文件,内容将被完全读入内存。

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


gru*_*gru 5

正如您可以在官方文档中阅读的那样:CSVParser#getRecords

返回的内容从流中的当前解析位置开始。

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

一般来说,我总是建议您从文档开始。通常,只需很少的阅读就可以轻松回答此类问题。如果仍然存在令人困惑的方面,社区当然很乐意为您提供进一步的帮助。