簡體   English   中英

用Java讀取大文件

[英]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

還有http://en.wikipedia.org/wiki/Memory-mapped_file

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM