2013-03-05 27 views
0

我正在處理大型CSV文件(數百MB)的應用程序。最近我遇到了一個問題,它最初在應用程序中看起來像是內存泄漏,但在經過一番調查後,似乎是格式不正確的CSV和CsvListReader嘗試解析永不結束的行的組合。其結果是,我有以下異常:將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

issue已被報道,而且我正在研究一些增強功能(對於將來的主要版本),目前應該使這兩個選項更容易一些。現在,你必須爲讀者提供你自己的Tokenizer(所以Super CSV使用你的Tokenizer而不是它自己的)。我建議帶上Super CSV的Tokenizer的副本並修改您的更改。這樣你就不必修改Super CSV,也不會浪費時間。

+0

感謝您的回答,對Tokenizer稍作修改,並根據您的建議使用它,以允許我防止內存問題並將超級CSV調整爲我的使用案例。也許最好創建一些更可配置的標記器,並使其成爲超級CSV庫的標準部分。我很樂意爲此提供幫助。 – dstefanox 2013-03-06 18:33:51