2017-05-31 45 views
1

在PHP中,我使用fopen(),fgets()fclose()來逐行讀取文件。它運作良好。但是我有一個腳本(從CLI運行)必須處理三百個5GB文本文件。這大約是30億fgets()。所以它工作得很好,但在這個規模下,微小的速度節省將會非常快速地加起來。所以我想知道是否有任何技巧來加速這個過程?更快的方式來逐行讀取文件?

我想到的唯一可能的事情是讓fgets()一次讀取多行。它看起來並不像它支持的那樣,但我在理論上可以讓連續說出20個$line[] = fgets($file);然後處理該數組。這與在一個命令中讀取多行不完全相同,因此可能沒有任何影響。但是我知道排隊你的mysql插入並將它們作爲一個巨大的插入(我將在經過更多測試和基準測試後在此腳本中實現的另一個技巧)將會節省大量時間。

+0

你可以嘗試讀取它「緩衝區緩衝區」,並再次分開線路 – modsfabio

+0

你嘗試使用fgetcsv函數嗎? –

+0

對於php腳本的mmap或createfilemapping會有幫助https://github.com/calcinai/php-mmap – tommybee

回答

0

可能更快的一種可能的方法是用fread()讀取文件的大塊,用換行符分割它,然後處理這些行。你必須考慮到這些塊可能會割斷線路,你必須檢測這些並將它們粘合在一起。

一般而言,您可以一次讀取的塊越大,您的過程應該變得越快。在可用內存的範圍內。

fread() docs來自:

注意FREAD()從文件指針的當前位置的讀取。使用ftell()來查找指針的當前位置,並使用rewind()來倒回指針位置。

+0

我將如何處理分割線?我想我可以保存在後面最後一個'換行'之後出現的任何內容,並將它粘貼到下一次閱讀的開頭。你怎麼知道fread()從哪裏讀取?或者像fgets一樣,當你不斷地調用它時,它是否會自動通過文件自動遞增? – l008com

+0

@ l008com是的。你需要一些變量來存儲在最後一個換行符後面出現的任何變量,並將它與下一個塊中第一個換行符之前的內容組合起來。 – Kempeth