2013-08-01 86 views
1

首先,我是Java的新手,我需要一些幫助解決以下問題。什麼是用Java讀取大量數據的有效方式

我有一個包含數百萬條記錄的Java列表。我想將這個數據列表導出爲CSV文件。以下是我爲讀取數據而寫入的功能,但它無法記錄數百萬條記錄。你能否建議更好的方法來做到這一點?

private String generateCsvData(List<Map<String, Object>> rows) { 

    String output = reportService.getReportHeadder(); 

    for (Map row : rows) { 

     output += (Long) row.get("branchId") 
       + "," 
       + StringEscapeUtils.escapeCsv((String) row.get("branches")) 
       + "," 
       + StringEscapeUtils.escapeCsv((String) row 
         .get("categoryName")) 
       + "," 
       + StringEscapeUtils.escapeCsv((String) row.get("products")) 
       + "," 
       + StringEscapeUtils.escapeCsv((String) row.get("emails")) 
       + "," 
       + StringEscapeUtils.escapeCsv((String) row 
         .get("contactAddress")) 
       + "," 
       + StringEscapeUtils.escapeCsv((String) row 
         .get("contactDet")) + "," 
       + StringEscapeUtils.escapeCsv((String) row.get("url")) 
       + "\n"; 

    } 

    return output; 
} 
+0

「失敗」是什麼意思?它會拋出異常嗎?什麼例外?順便問一下,在哪裏閱讀?我看到你正在將一些數據轉換爲CSV格式。我不認爲這是閱讀。 –

+0

@NikitaBeloglazov我會懷疑在這種情況下OutOfMemoryError ... – assylias

+0

'OutOfMemoryError'是假設? –

回答

1

在寫入文件之前,您將所有內容都存儲在字符串中,如果您在生成文件時逐行寫入文件,該怎麼辦?

2

問題是,您正在創建一個veeeery長字符串,然後想將其寫入文件。

此外,你正在創建一個新的字符串,每串聯你連接。在這些情況下,使用StringBuilder

您必須使用流順序寫入。 basic io開始學習的好點

1

使用CSV庫,例如OpenCSV

您可以逐行處理文件 - 讀取一行,然後對其進行處理,然後再將其丟棄。這樣,最多隻有一行文件在內存中。

3

是的,輕鬆愉快。

如果您打算一次將所有記錄保存在內存中,則說明存在問題。你的機器只有很多內存,只有一部分被分配給JVM。當你填充它時,遊戲結束。您已有Map中的數據。當你必須同時存儲.csv表示時,會使問題加倍。

一個解決方案是一次流出一行。您可以迭代Map並僅存儲一次數據。

另一種解決方案可能是將所有數據存儲在關係數據庫表中。您可以遍歷ResultSet並以此方式將結果以流方式傳輸。現在你真的減少了你的內存需求。

您創建行的機制不好。我更喜歡連接上的StringBuilder

0

爲什麼不使用像Spring Batch這樣的框架,它將塊操作從理論上寫得很多!!!!!!!記錄

1

首先,如果您在一個循環中構造一個字符串,請不要連接字符串,但我們使用StringBuilder,因爲它通常會更好,並且不會使用大量中間字符串來垃圾回憶。

但是在這種情況下,我建議不要將所有內容都放在內存中,而是在處理過程中直接寫入文件。這將減少所需的內存。查看PrintWriter或查找已經完成所需內容的庫(例如OpenCSV)。

相關問題