在通常的學習和開發中,因為我們很少會接觸到大量數據的讀取和寫入,所以當突然有了這種需求的時候,我們可
能仍然會按照一些比較快捷的方法,像file_get_contents,fread等方法來讀取文件,不過這樣以來如果讀取的文件太
大,就會產生問題,在實現大文件讀取和寫入的時候查找了網上的一些資料,不過有些例子給的不是很符合我的需
求,所以我就結合網上已有的例子,再寫一篇總結性的博客吧。
那么究竟會產生什么問題呢,這就要說一些PHP的底層實現數,file_get_contents和fread來說一下,首先說一下
PHP中文件讀取的函數,file_get_contents和fread,這兩個函數其實原理是相同的,都是讀取內容到系統的內存中,
不過如果只是想將一個文件的內容讀入到一個字符串中,請使用file_get_contents(),它的性能比 fread() 好得多。
在讀取不是很大的文件還是沒有問題的,不過當讀取大文件的時候(例如2GB的日志),如果你機器的內存只有4G,
如果你將整個文件全部讀取然后存入字符串中,就可能會導致系統的內存爆掉造成卡死,因為還有一部分內存要用于
維持系統的運行和其他進程的運行,既然會這樣,我們就需要一些其他辦法來避免一次性讀取太多的內容,通過這種
辦法來實現大文件的讀取。
PHP文件讀?。?/p>
下面這個是網上讀取大文件的一個例子,來說明上面內存會爆掉的現象。。
_________________________________無敵分割線_______________________________________
我機器是2個G的內存,當按下F5運行時,系統直接變灰,差不多20分鐘后才恢復過來,可見將這么大的文件全部直接讀入內存,后果是多少嚴重,所以不在萬不得以,memory_limit這東西不能調得太高,否則只有打電話給機房,讓reset機器了.
_____________________________________無敵分割線_____________________________________上面的例子雖然是讀取最后幾行的例子,不過由于對文件的內容進行了遍歷,所以跟讀取整個文件是一樣的,不過如
果是為了讀取最后幾行的內容,也可以直接用fseek來進行定位讀取部分內容。
下面我們來一起探討下如何對大文件進行讀取和寫入。
大文件讀取:
因為要求讀取部分,如果文件不是特別大,可以通過file_get_contents或fread自帶的分割參數來進行分塊來進行讀?。ㄟ@個地方感覺需要加一個sleep函數,來減少IO的峰值大小,不過不知是否正確,希望大牛指點),還有一種方法,就是通過while循環,用fgets來進行逐行的讀取,因為fgetss是通過文件指針讀取一行,效率是比較高的。
下面附上通過fgets實現的大文件讀取并對文件內容進行編碼轉換(UTF-8 -> GBK)的例子,代碼如下:
$file = fopen($old_file_path,"r"); $result = fopen($temporary_file_path,"a"); $re_sign = 0; while(!feof($file)) { $content = fgets($file); $encode = mb_detect_encoding($content, array('ASCII','UTF-8','GB2312','GBK','BIG5')); if ($encode == 'UTF-8') { $str = iconv($encode,"GBK//IGNORE", $content); $encode = mb_detect_encoding($content, array('ASCII','UTF-8','GB2312','GBK','BIG5')); fwrite($result, $str); $re_sign = 1; } else { fwrite($result, $content); } } fclose($file); fclose($result); if($re_sign == 1){ rename($old_file_path, $old_file_path . '.bak' ); rename($temporary_file_path, $old_file_path); } else { unlink($temporary_file_path); }
大文件寫入:
大文件的寫入相對大文件讀取來說產生的代價不是很大,因為文件寫入是寫入到硬盤中,如果一次性寫入文件過多,
只會產生卡硬盤的現象,如果從效率上來講一次性直接寫入的耗時和效率最高,所以大文件的寫入的話建議一次性讀取后直接寫入文件中。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答