国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

PHP大文件的讀取和寫入問題

2020-03-22 17:54:19
字體:
來源:轉載
供稿:網友
  • 在通常的學習和開發中,因為我們很少會接觸到大量數據的讀取和寫入,所以當突然有了這種需求的時候,我們可

    能仍然會按照一些比較快捷的方法,像file_get_contents,fread等方法來讀取文件,不過這樣以來如果讀取的文件太

    大,就會產生問題,在實現大文件讀取和寫入的時候查找了網上的一些資料,不過有些例子給的不是很符合我的需

    求,所以我就結合網上已有的例子,再寫一篇總結性的博客吧。

    那么究竟會產生什么問題呢,這就要說一些PHP的底層實現數,file_get_contents和fread來說一下,首先說一下

    PHP中文件讀取的函數,file_get_contents和fread,這兩個函數其實原理是相同的,都是讀取內容到系統的內存中,

    不過如果只是想將一個文件的內容讀入到一個字符串中,請使用file_get_contents(),它的性能比 fread() 好得多。

    在讀取不是很大的文件還是沒有問題的,不過當讀取大文件的時候(例如2GB的日志),如果你機器的內存只有4G,

    如果你將整個文件全部讀取然后存入字符串中,就可能會導致系統的內存爆掉造成卡死,因為還有一部分內存要用于

    維持系統的運行和其他進程的運行,既然會這樣,我們就需要一些其他辦法來避免一次性讀取太多的內容,通過這種

    辦法來實現大文件的讀取。

    PHP文件讀取:

    下面這個是網上讀取大文件的一個例子,來說明上面內存會爆掉的現象。。

    _________________________________無敵分割線_______________________________________


    需求如下: 現有一個1G左右的日志文件,大約有500多萬行, 用php返回最后幾行的內容。

    實現方法:

    1. 直接采用file函數來操作
    注:由于 file函數是一次性將所有內容讀入內存,而php為了防止一些寫的比較糟糕的程序占用太多的內存而導致系統內存不足,使服務器出現宕機,所以默認情況下限制只能最大使用內存16M,這是通過php.ini里的memory_limit = 16M來進行設置,這個值如果設置-1,則內存使用量不受限制.

    下面是一段用file來取出這具文件最后一行的代碼.
    整個代碼執行完成耗時 116.9613 (s).
    php對大文件進行讀取操作【OK】 - PHP程序員 - 李國華【PHP程序員C++】博客

    我機器是2個G的內存,當按下F5運行時,系統直接變灰,差不多20分鐘后才恢復過來,可見將這么大的文件全部直接讀入內存,后果是多少嚴重,所以不在萬不得以,memory_limit這東西不能調得太高,否則只有打電話給機房,讓reset機器了.

    _____________________________________無敵分割線_____________________________________

    上面的例子雖然是讀取最后幾行的例子,不過由于對文件的內容進行了遍歷,所以跟讀取整個文件是一樣的,不過如

    果是為了讀取最后幾行的內容,也可以直接用fseek來進行定位讀取部分內容。

    下面我們來一起探討下如何對大文件進行讀取和寫入。

    大文件讀?。?/p>

    因為要求讀取部分,如果文件不是特別大,可以通過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);            }

    大文件寫入:

    大文件的寫入相對大文件讀取來說產生的代價不是很大,因為文件寫入是寫入到硬盤中,如果一次性寫入文件過多,

    只會產生卡硬盤的現象,如果從效率上來講一次性直接寫入的耗時和效率最高,所以大文件的寫入的話建議一次性讀取后直接寫入文件中。

    PHP編程

    鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

  • 發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    主站蜘蛛池模板: 娄烦县| 类乌齐县| 武山县| 玉环县| 莆田市| 固安县| 崇义县| 黄龙县| 海宁市| 绵竹市| 宁夏| 四川省| 克什克腾旗| 青岛市| 大化| 霍林郭勒市| 离岛区| 仁怀市| 榆林市| 中方县| 永修县| 灯塔市| 千阳县| 衡阳市| 鄂托克前旗| 辽阳市| 浠水县| 健康| 珲春市| 娄底市| 黄石市| 双峰县| 华安县| 滦平县| 泰安市| 安远县| 绥阳县| 潍坊市| 桂平市| 邯郸市| 禄劝|