[英]Reading huge file in Java
我讀了一個巨大的File
(近500萬行)。 每行包含Date和一個Request ,我必須在具體的** Date **之間解析Requests。 我使用BufferedReader
讀取File
直到開始Date
然后開始解析行。 我可以使用Thread
來解析行嗎,因為這會花費很多時間?
並行處理許多小任務的一個好方法是用FutureTask包裝每個任務的處理,然后將每個任務傳遞給ThreadPoolExecutor來運行它們。 應該使用系統可用的CPU內核數來初始化執行程序。
當您調用executor.execute(future)
,將來將排隊等待后台處理。 為了避免創建和銷毀過多的線程,ScheduledThreadPoolExecutor將僅創建您指定的數量的線程,並一個接一個地執行期貨。
要檢索future的結果,請調用future.get()
。 當未來尚未完成(或什至尚未開始)時,此方法將凍結直到完成。 但是當您等待時,其他期貨也會在后台執行。
請記住,當您不再需要executor.shutdown()
時,請確保它終止了它在后台的線程,否則該線程將一直保持到Keepalive時間到期或被垃圾回收為止。
tl; dr偽代碼:
create executor
for each line in file
create new FutureTask which parses that line
pass future task to executor
add future task to a list
for each entry in task list
call entry.get() to retrieve result
executor.shutdown()
您的問題尚不完全清楚,但是聽起來好像您每次客戶請求數據時都在重新解析500萬行的文件。 您當然可以通過拋出更多的線程和更多的CPU內核來解決該問題,但是更好的解決方案是通過消除重復的工作來提高應用程序的效率。
在這種情況下,您應該重新設計應用程序,以避免在每次請求時重新解析整個文件。 理想情況下,您應該將數據存儲在數據庫或內存中,而不是在每次請求時都處理平面文本文件。 然后根據請求在數據庫或內存數據結構中查找信息。
如果無法完全消除500萬行的文件,則可以定期重新檢查大文件的更改,跳過/查找到最后一條已解析的記錄的末尾,然后僅解析新記錄並更新數據庫或內存中的數據結構體。 所有這些都可以選擇在單獨的線程中完成。
首先,500萬行(每行1000個字符)只有5Gb,這對於JVM而言並不一定是禁止的。 如果這實際上是一個命中率很高的關鍵用例,那么購買更多的內存幾乎肯定是正確的選擇。
其次,如果不可能的話,最有可能正確的做法是根據日期構建有序地圖。 因此,每個日期都是地圖中的鍵,並且指向包含請求的行號列表。 然后,您可以直接轉到相關的行號。
形式的東西
HashMap<Date, ArrayList<String>> ()
會很好。 那應該具有5,000,000 * 32/8字節= 20Mb的內存使用量,應該沒問題。
您還可以使用FileChannel類在從在線跳轉到另一行時保持I / O句柄打開。 這允許內存映射。
參見http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.