Apache Commons CSV项目非常适合解析逗号分隔的值,制表符分隔的数据和类似的数据格式。
我的印象是,该工具完全读取文件,并将生成的行对象保存在内存中。但我不确定,我找不到有关此行为的任何文档。
对于非常大的解析,我想进行增量读取,一次一行,或者一次相对较少的行数,以避免压倒性的内存限制。
仅就内存使用方面而言,这里的想法类似于 XML 的 SAX 解析器如何增量读取以最大程度地减少 RAM 的使用,而 DOM 样式的 XML 解析器将文档完全读入内存以提供树遍历。
问题:
- Apache Commons CSV在读取文档方面的默认行为是什么:完全进入内存,还是增量?
- 是否可以在增量文档和整个文档之间更改此行为?
我的印象是这个工具完全读取一个文件,结果的行对象保存在内存中
不。内存的使用取决于您选择如何与CSVParser
对象交互。
Javadoc forCSVParser
在其部分解析记录与解析内存中明确解决了这个问题,但需要注意:
解析到内存可能会消耗大量系统资源,具体取决于输入。例如,如果您正在解析 150MB 的 CSV 数据文件,则内容将完全读入内存。
我快速浏览了源代码,确实解析记录似乎一次从其输入源中读取一个块,而不是一次全部读取。但你自己看看。
明智地解析记录
在解析记录部分中,它显示了如何通过循环CSVParser
Iterable
来增量读取一次一个CSVRecord
。
CSVParser parser = CSVParser.parse(csvData, CSVFormat.RFC4180);
for (CSVRecord csvRecord : parser) {
...
}
解析到内存中
相比之下,解析到内存部分显示了如何使用CSVParser::getRecords
将所有CSVRecord
对象一次性加载到内存中的List
中。因此,很明显,非常大的输入文件可能会耗尽受限机器上的内存。
Reader in = new StringReader("a;bnc;d");
CSVParser parser = new CSVParser(in, CSVFormat.EXCEL);
List<CSVRecord> list = parser.getRecords();