84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
参考: 有一个1G大小的一个文件,内存限制大小是10M,有序返回频数最高的50个词,该怎么做?
网上有很多该问题的解决方案,都是用分而治之的思想,提到了遍历整个文件。
那么我的问题是:如果单纯地逐行读取大文件,算是把1G文件全都加载进内存吗?或者说是读取大于内存的文件应该怎么读?
认证0级讲师
在這裡記憶體就像一條管道,逐行讀是把1G檔案在記憶體裡過一遍而已,10M表示管道的粗細。 所以,逐行讀是把1G檔加载进去过記憶體。
加载进去过
try (BufferedReader in = new BufferedReader(new FileReader(file))) { String line; while ((line = in.readLine()) != null) { // parse line } }
file再大,只要每一行的長度有限,整個檔案讀完會需要不少的時間,但不會佔用太大的記憶體。
分塊讀,每讀一個塊一個結果集,最後對結果集聚合處理文本的話,知道行數會更好
linux上面有个指令叫做split可以並發快速把大文本分割成小的文件,然後處理就方便了呀,這種算法叫做外排序
linux
split
內存就好比草稿紙,寫滿一篇就翻篇。 用過、沒用的數據就丟掉了。
簡單舉例,創建一個變數 buff,設定好它的大小,打開檔案流往裡填,填滿以後查你要的內容,查到就統計到另外一個變數裡計數。 然後清空buff,繼續之前讀取的位置再次裝載內容… 直到讀取完畢,統計也就完成了。
針對不同的系統,都會提供一個API來操作大於記憶體的文件,也就是將文件當作記憶體來處理:
内存映射
mmap
CreateFileMapping
在這裡記憶體就像一條管道,逐行讀是把1G檔案在記憶體裡過一遍而已,10M表示管道的粗細。
所以,逐行讀是把1G檔
加载进去过
記憶體。file再大,只要每一行的長度有限,整個檔案讀完會需要不少的時間,但不會佔用太大的記憶體。
分塊讀,每讀一個塊一個結果集,最後對結果集聚合
處理文本的話,知道行數會更好
linux
上面有个指令叫做split
可以並發快速把大文本分割成小的文件,然後處理就方便了呀,這種算法叫做外排序內存就好比草稿紙,寫滿一篇就翻篇。 用過、沒用的數據就丟掉了。
簡單舉例,創建一個變數 buff,設定好它的大小,打開檔案流往裡填,填滿以後查你要的內容,查到就統計到另外一個變數裡計數。 然後清空buff,繼續之前讀取的位置再次裝載內容… 直到讀取完畢,統計也就完成了。
針對不同的系統,都會提供一個API來操作大於記憶體的文件,也就是將文件當作記憶體來處理:
内存映射
mmap
CreateFileMapping