将CsvListReader限制为一行

时间:2013-03-05 12:16:30

标签: supercsv

我正在处理处理大型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中有一些明确的方法吗?

1 个答案:

答案 0 :(得分:1)

已经报告了issue,我正在研究一些增强功能(对于未来的主要版本),这一点应该会使两个选项更容易。

目前,您必须向阅读器提供您自己的Tokenizer(因此Super CSV使用您的自己而不是自己的)。我建议您复制一份Super CSV的Tokenizer并根据您的更改进行修改。这样您就不必修改超级CSV,也不会浪费时间。