回覆列表
-
1 # 程式設計師小助手
-
2 # TonyDeng
有與低階檔案流介面的語言即可,典型如C/C++。很多高階語言都有,看你用哪種了。處理方式,都是分段讀寫,不二之選,不要一下子讀入記憶體。
-
3 # 程式碼接盤俠
用RandomAccessfile的類方法進行讀取檔案,會比一般的方法快很多,再用bufferwriter把得到的結果寫進txt中。
-
4 # 李老師tome
對於大文字檔案(超過記憶體大小的檔案),通常是無法直接載入至記憶體的。所以問題就不在用何種程式語言,而在於用什麼方法了。我通常用以下方法:
首先將大檔案進行分割,並打上標記。
然後使用多執行緒對各個檔案進行處理。
最後將處理的結果進行統計。
如果你用到JAVA的話,我覺得可以使用以下兩種方法進行讀操作:
傳統的Block IO,這個可以直接讀取單個大檔案,直接交由JAVA的BufferedReader去處理。(這種方式是執行緒阻塞的,請注意異常處理。)
NIO方式,這種也是我上面提到的方式,拆分檔案,利用位元組流陣列,處理拆分後的檔案,再進行彙總處理。(這種方式要注意拆分的檔案不要過大。)
結論:大文字檔案,遠超記憶體,需要格外注意。
前言生產伺服器中經常產生很多檔案,有些積年累月單個檔案,體積越來越大。
本文使用多種程式語言,實現大檔案的讀取。
PHP的處理方式大檔案如果直接open,就會被整個寫入記憶體,記憶體是吃不消的。比如4G的記憶體,10G的檔案,這是處理不了的。也沒有哪個文字編輯器可以用。
常用的file_get_contents函式,是將檔案內容讀入到字串變數內。而字串變數分配在記憶體,所以沒有任何辦法處理大檔案。
一般的做法是使用 fgets 函式。該函式從檔案內讀取一行。函式格式如下:
string fgets ( resource [, int ] )其中引數 $handle 是檔案指標,從 $handle 指向的檔案中讀取一行並返回長度最多為 $length - 1 位元組的字串。
碰到換行符(包括在返回值中)、EOF 或者已經讀取了 $length - 1 位元組後停止(看先碰到那一種情況)。如果沒有指定 $length,則預設為 1K,或者說 1024 位元組。
實際用起來像下面這樣。
此函式效率極高,一次最多讀一行。而碰到整個檔案都是一行的情況,則按照設定的 $length 按照長度依次讀取。
Python的方式從上述PHP的處理方法可以看到,關鍵點是按行讀取,再按長度讀取。python的處理方法一樣,只是摻雜了一些語法糖。
python有一個“生成器”,解決大檔案的讀取,就靠這個玩意兒。
在python的函式(function)定義中,只要出現了yield表示式(Yield expression),那麼事實上定義的是一個generator function, 呼叫這個generator function返回值是一個generator。
為什麼genetor效率高呢,因為其與普通函式的有區別:
function每次都是從第一行開始執行,而generator從上一次yield開始的地方執行。
function呼叫一次返回一個(一組)值,而generator可以多次返回。
function可以被無數次重複呼叫,而一個generator例項在yield最後一個值或者return之後就不能繼續呼叫了。
下面是使用帶有yield關鍵字的讀取大檔案方法。
其實python還有更優雅便捷的寫法,就是for迴圈讀取。像下面這樣:
或者不用重新定義函式,直接用for迴圈遍歷。
底層使用的原理是一樣的。
Golang的方式Golang的想法也一樣,它絕不把整個檔案寫入記憶體。bufio庫就是讀寫檔案的利器。
不多解釋,直接上示例。
Golang為了統一場景,無論普遍的和特殊的,都考慮在內了。這就是bufio的厲害之處。
對於讀寫,資料被儲存直到達到特定大小,透過這種方式觸發的寫操作更少。同時還減少了 sycall(系統呼叫)的數量,卻可以使用更高效的方式使用底層硬體。
Linux下的工具如果你在Linux處理該文字,那這完全不是問題。自帶的很多工具,能夠幫你處理這個簡單的問題。比如 head,讀取某檔案的前多少行;tail,讀取某檔案的最後多少行。
如果只是要讀檔案,那麼 less 是你最佳的選擇。
文件內說的很清楚,less並不直接讀入整個文件,因此處理起來,比vi/vim編輯器速度快的多。
開啟之後,就可以上下翻頁閱讀了。
結語本文透過多種程式語言,實現了大檔案的讀取。
掌握核心的方法後,使用哪種語言實現,都可以。