我正在开发处理大型 CSV 文件(数百 MB)的应用程序。最近我遇到了一个问题,起初看起来像是应用程序中的内存泄漏,但经过一番调查,它似乎是格式错误的 CSV 和 CsvListReader 尝试解析永无止境的行的组合。结果,我得到了以下异常:
at java.lang.OutOfMemoryError.<init>(<unknown string>)
at java.util.Arrays.copyOf(<unknown string>)
Local Variable: char[]#13624
at java.lang.AbstractStringBuilder.expandCapacity(<unknown string>)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(<unknown string>)
at java.lang.AbstractStringBuilder.append(<unknown string>)
at java.lang.StringBuilder.append(<unknown string>)
Local Variable: java.lang.StringBuilder#3
at org.supercsv.io.Tokenizer.readStringList(<unknown string>)
Local Variable: java.util.ArrayList#642
Local Variable: org.supercsv.io.Tokenizer#1
Local Variable: org.supercsv.io.PARSERSTATE#2
Local Variable: java.lang.String#14960
at org.supercsv.io.CsvListReader.read(<unknown string>)
通过基于转储结果分析堆转储和 CSV 文件,我注意到 CSV 行之一中的一列缺少右引号,这显然导致读者试图通过将文件内容附加到内部字符串缓冲区直到出现不再是堆内存。
无论如何,这就是问题所在,这是由于 CSV 格式错误 - 一旦我删除了关键行,问题就消失了。我想要实现的是告诉读者:
- 它应该解释的所有内容总是以换行符结尾,即使引号没有正确关闭(不支持多行)
- 或者,提供 CSV 行的特定限制(以字节为单位)
使用 CsvListReader(在我的情况下首选)在 SuperCSV 中是否有一些明确的方法可以做到这一点?