2017-05-06 184 views
3

我正在嘗試使用Java讀取1,000,000行CSV文件。我正在使用OpenCSV庫,它可以在30,000行的較小文件上正常工作。在不到半秒的時間內處理它。但是當我嘗試從一百萬行文件中讀取時,它永遠不會結束。在Java中讀取大型CSV文件

現在我測試看看,什麼時候會真正停止,並用自己的二進制搜索的版本,我第一次嘗試閱讀500K線,然後250K,等等,我發現它容易讀數145k行,在0.5-0.7sec,而150k甚至沒有完成。

我已經徹底搜索過,發現了幾個我在代碼中使用的解決方案,例如使用BufferedReader,BufferedInputStream等,但沒有一個解決了它。仍然失敗145-150k線。

這是我的代碼的相關部分(交換150000與145000是什麼原因導致的程序在< 1秒執行):

try { 
     // BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("myFile.csv")); 
     CSVReader csvReader = new CSVReader(new InputStreamReader 
       (new BufferedInputStream(new FileInputStream("myFile.csv"), 8192 * 32))); 
     try { 
      int count = 0; 
      String[] line; 
      long timeStart = System.nanoTime(); 
      while((line = csvReader.readNext()) != null){ 
       count ++; 
       if(count >= 150000){ 
        break; 
       } 
      } 
      long timeEnd = System.nanoTime(); 
      System.out.println("Count: " + count); 
      System.out.println("Time: " + (timeEnd - timeStart) * 1.0/1000000000 + " sec"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } catch (FileNotFoundException e) { 
     System.out.println("File not found"); 
    } 

正如你所看到的,我已嘗試設置一個更大的緩衝大小也是如此。我嘗試過Readers,Input Streams等各種組合,沒有什麼真正有所作爲。

我想知道我該怎麼做?有沒有辦法閱讀,一次說10萬行,然後繼續閱讀下一個100K?

此外,我接受任何其他解決方案,其中不一定包含OpenCSV庫。我只是用它來簡單地解析一個csv文件。

+0

當你說'永遠不會結束'......它到底是什麼?死鎖,內存不足等......使用調試器來查看它到底是什麼,或者在循環中放入一些系統信息以查看它是否仍在處理中,但速度很慢? – Adam

回答

2

也許問題不在於CSV文件中的行數,而是它的內容。也許有一些數據在145k到150k之間,這會導致你的應用程序永遠不會完成。

如果您複製文件中的第一行145k行並將其粘貼到新的CSV文件中,直到它有1m行,您可以檢查它。如果您的應用程序可以處理這個新文件,那麼問題出現在數據中,而不是行數。

3

我只是看了一下OpenCSV的實現,我沒有看到任何可以解釋這種行爲的東西,只是因爲文件很大並且包含大量記錄。

但OpenCSV能夠處理多行數據,從網站:

處理帶有嵌入式回車(跨多行即項)引用條目。

我認爲在您的情況下,有一條記錄 - 第150k條記錄的某處 - 包含錯誤的引用條目。默認的引用字符是"。這可能是一個紀錄,如:

value,value,"badvalue,value 
value,value,value,value 

在這種情況下,所使用的OpenCSV IST設置爲掛起狀態,即讀取記錄繼續在下一行的解析器。並且撥打CSVReader.readNext()會嘗試讀取儘可能多的行以完成csv記錄。如果沒有不匹配錯位的引用字符,它將讀取和讀取並讀取,直到緩衝區耗盡或發生其他錯誤。

要查找記錄,您可以像讀取文件一樣讀取記錄,對記錄進行計數並打印出當前計數。這會給你最後一個有效記錄的編號,然後會像現在一樣停止/掛起。

然後,我會寫一個新的程序,它只是逐行讀取文件(不使用CSVParser,只是簡單的行),並跳過你認爲很好的行數。然後從那裏打印大約10行,並且您有一些數據要分析。

+0

我同意P.J.和Marat的問題是數據。如果你想繼續使用與上面相同的程序,我會考慮以二進制方式縮小數字(145K,所以使用147K,然後是148K,等等),以便在開始永久使用時縮小範圍。然後,您可以查看實際文件中的該行(以及上方/下方的行),以查看數據開始變形的位置。 –