萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP讀取大文件的類SplFileObject使用介紹

PHP讀取大文件的類SplFileObject使用介紹

 一般讀取文件我們用fopen 或者 file_get_contents ,前者可以循環讀取,後者可以一次性讀取,但都是將文件內容一次性加載來操作。

如果加載的文件特別大時,如幾百M,上G時,這時性能就降下來了,那麼PHP裡有沒有對大文件的處理函數或者類呢? 答案是:有的。 PHP真的越來越“面向對象”了,一些原有的基礎的SPL方法都開始陸續地實現出class了。 從 PHP 5.1.0 開始,SPL 庫增加了 SplFileObject 與 SplFileInfo 兩個標准的文件操作類。SplFileInfo 是從 PHP 5.1.2 開始實現的。 從字面意思理解看,可以看出 SplFileObject 要比 SplFileInfo 更為強大。 不錯,SplFileInfo 僅用於獲取文件的一些屬性信息,如文件大小、文件訪問時間、文件修改時間、後綴名等值,而 SplFileObject 是繼承 SplFileInfo 這些功能的。    代碼如下:/** 返回文件從X行到Y行的內容(支持php5、php4)    * @param string $filename 文件名  * @param int $startLine 開始的行數  * @param int $endLine 結束的行數  * @return string  */ function getFileLines($filename, $startLine = 1, $endLine=50, $method='rb') {     $content = array();     $count = $endLine - $startLine;       // 判斷php版本(因為要用到SplFileObject,PHP>=5.1.0)     if(version_compare(PHP_VERSION, '5.1.0', '>=')){         $fp = new SplFileObject($filename, $method);         $fp->seek($startLine-1);// 轉到第N行, seek方法參數從0開始計數         for($i = 0; $i <= $count; ++$i) {             $content[]=$fp->current();// current()獲取當前行內容             $fp->next();// 下一行         }     }else{//PHP<5.1         $fp = fopen($filename, $method);         if(!$fp) return 'error:can not read file';         for ($i=1;$i<$startLine;++$i) {// 跳過前$startLine行             fgets($fp);         }         for($i;$i<=$endLine;++$i){             $content[]=fgets($fp);// 讀取文件行內容         }         fclose($fp);     }     return array_filter($content); // array_filter過濾:false,null,'' }     Ps: 上面都沒加”讀取到末尾的判斷”:!$fp->eof() 或者 !feof($fp),加上這個判斷影響效率,自己加上測試很多很多很多行的運行時間就曉得了,而且這裡加上也完全沒必要。 從上面的函數就可以看出來使用SplFileObject比下面的fgets要快多了,特別是文件行數非常多、並且要取後面的內容的時候。fgets要兩個循環才可以,並且要循環$endLine次。 此方法花了不少功夫,測試了很多中寫法,就是想得出效率最高的方法。哪位覺得有值得改進的歡迎賜教。 使用,返回35270行-35280行的內容:  代碼如下:echo '<pre>'; var_dump(getFileLines('test.php',35270,35280)); echo '</pre>';    
copyright © 萬盛學電腦網 all rights reserved