PHP實現讀取乙個1G的檔案大小

2022-07-13 08:09:08 字數 1476 閱讀 1528

需求如下: 現有乙個1g左右的日誌檔案,大約有500多萬行, 用php返回最後幾行的內容。

1. 直接採用file函式來操作 or file_get_content() 肯定報記憶體溢位

注: 由於 file函式是一次性將所有內容讀入記憶體,而php為了防止一些寫的比較糟糕的程式占用太多的記憶體而導致系統記憶體不足,使伺服器出現宕機,所以預設情況下限制只能最大使用記憶體16m, 這是通過php.ini裡的memory_limit = 16m來進行設定,這個值如果設定-1,則記憶體使用量不受限制.

下面是一段用file來取出這具檔案最後一行的**.

ini_set('memory_limit','-1');

$file = 'access.log';

$data = file($file

);$line = $data[count($data)-1];

這裡有個問題,假如伺服器的記憶體只有256mb,那麼上面的方法就不行了,解決方法就操作檔案指標,例如下面的**

2. 直接使用php的fseek來進行檔案操作

這種方式是最為普遍的方式,它不需要將檔案的內容全部讀入記憶體,而是直接通過指標來操作,所以效率是相當高效的.在使用fseek來對檔案進行操作時,也有多種不同的方法,效率可能也是略有差別的,下面是常用的兩種方法.

方法一

首先通過fseek找到檔案的最後一位eof,然後找最後一行的起始位置,取這一行的資料,再找次一行的起始位置,再取這一行的位置,依次類推,直到找到了$num行。

function tail($fp,$n,$base=5)

catch (exception$e)

$pos *= $base

;

while(!feof($fp

)) }

return

array_slice($lines,0,$n);}

var_dump(tail(fopen("access.log","r+"),10));

方法二

還是採用fseek的方式從檔案最後開始讀,但這時不是一位一位的讀,而是一塊一塊的讀,每讀一塊資料時,就將讀取後的資料放在乙個buf裡,然後通過換行符(\n)的個數來判斷是否已經讀完最後$num行資料.

實現**如下

$fp = fopen($file, "r");

$line = 10;

$pos = -2;

$t = " ";

$data = "";

while ($line > 0)

$t = " ";

$data .= fgets($fp

);

$line --;

}fclose ($fp

);echo

$data

電郵服務商都瘋了,又乙個1G免費郵箱!

乙個叫walla的以色列網路公司,在繼google之後也推出1g免費郵箱。不需要邀請,就算數月不登陸帳號也不會取消。很明顯,這一切都是衝著google來的。對於推出1g免費郵箱,該公司的ceo是這樣說的 最初,我們打算將郵箱容量提公升到100mb。但當聽說了google的gmail之後,我們發覺我們...

17 18 實現乙個讀取INI檔案的類

開發環境 vs2013,win10 經過很多次修改,和對一些錯誤的學習,才搞定了這麼乙個類 比如說lpctstr的賦值,new和delete要成對出現,字元陣列和字串的庫函式去取代自己寫字串處理函式等,wcsncpy s用法,string類的賦值運算子等。標頭檔案 對文字的處理要求 號之前強制為整數...

提供乙個讀取CAP檔案的類

capfilereader類使用說明 功能 讀取ethreal生成的cap格式的檔案內的資訊 介面說明 capfilereader void 預設建構函式 capfilereader void 析構函式 bool open const char capfile 開啟cap檔案,引數為檔案的路徑 bo...