//普通的文件读取一个2.4G的SQL导出文件$fileName='./2020-02-23.sql';//file_get_contents$fileInfo=file_get_contents($fileName);//Fatalerror:Allowedmemorysizeof134217728bytesexhausted//file$fileInfo=file($fileName);//Fatalerror:Allowedmemorysizeof134217728bytesexhausted//fopen+fread$fileHandle=fopen($fileName,'r');$fileInfo=fread($fileHandle,filesize($fileName));//Fatalerror:Allowedmemorysizeof134217728bytesexhausted
上述三种形式的文件加载读取办法都是不能加载这么大的文件的,当然,你也可以修正 php.ini 中的干系配置让他们能够加载成功,但我们并不推举这样利用,毕竟内存资源比较硬盘资源还是要宝贵的多。
以下的办法是可以直接读取这种大文件的:
//readfile只能直接输出echoreadfile($fileName);//fopen+fgetc如果单$fileHandle=fopen($fileName,'r');//输出单字符直到end-of-filewhile(!feof($fileHandle)){echofgetc($fileHandle);}fclose($fileHandle);//SplFileObject$fileObject=newSplFileObject($fileName,'r');while(!$fileObject->eof()){echo$fileObject->fgetc();}
第一个 readfile() ,读取文件后就直接打印了,不能进行其他操作,适用于直接显示大文件内容时利用。
第二个 fopen() 合营 fgetc() 或 fgets() 是读取这种大文件的标配。fopen() 获取文件句柄,fgetc() 按字符读取,fgets() 按行读取。像这个 mysqldump 出来的文件,一行也可能非常的大,以是我们就只能直接按字符读取。
第三个是SPL扩展库为我们供应的面向工具式的 fopen() 操作,建议新的开拓中如果有读取大文件的需求最好利用这种形式的写法,毕竟SPL函数库已经是PHP的标准函数库了,而且面向工具的操作形式也更加的主流。
上面三种读取办法都有一个要把稳的点是,我们将大文件读取后不应该再保存到变量中,该当直接打印显示、入库或者写到其他文件中。由于直接读取到一个变量中就和前面的直接读取到内存的办法一样了,那还不如直接去修正下 php.ini 的配置然后利用最上方的办法直接读取到内存方便。还是那句话,内存留给真正须要它的地方,这种大文件,最好还是进行硬盘的IO操作。
测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/202003/source/PHP%E5%A4%A7%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E6%93%8D%E4%BD%9C.php
参考文档: 《PHP7编程实战》