当前位置: 首页 > 后端技术 > PHP

PHP大文件读取操作

时间:2023-03-30 04:18:47 PHP

简单文件读取,一般我们会使用file_get_contents()直接获取文件内容。但是这个函数有个比较严重的问题就是它会一次性把文件加载到内存中,也就是会受到内存的限制。因此,在加载大文件时一定不要使用该方法。我们先来看一个这样加载的例子。//普通文件读取一个2.4G的SQL导出文件$fileName='./2020-02-23.sql';//file_get_contents$fileInfo=file_get_contents($fileName);//Fatalerror:Allowedmemorysizeof134217728bytesexhausted//file$fileInfo=file($fileName);//致命错误:允许的内存大小为134217728字节耗尽//fopen+fread$fileHandle=fopen($fileName,'r');$fileInfo=fread($fileHandle,filesize($fileName));//Fatalerror:Allowedmemorysizeof134217728bytesexhausted以上三种形式的文件加载和读取方式无法加载这么大的文件。当然你也可以修改php.ini。ini中的相关配置可以让它们加载成功,但是我们不推荐这样使用,毕竟内存资源比硬盘资源宝贵得多。下面的方法可以直接读取这么大的文件://readfile只能直接输出echoreadfile($fileName);//fopen+fgetcifonly$fileHandle=fopen($fileName,'r');//输出单个字符直到文件结束while(!feof($fileHandle)){echofgetc($fileHandle);}fclose($fileHandle);//SplFileObject$fileObject=newSplFileObject($fileName,'r');while(!$fileObject->eof()){echo$fileObject->fgetc();}第一个readfile(),读取文件后直接打印,不能进行其他操作。适合直接显示大文件内容使用。带有fgetc()或fgets()的第二个fopen()是读取此类大文件的标准。fopen()获取文件句柄,fgetc()按字符读取,fgets()按行读取。像这个mysqldump文件,一行可能会很大,所以我们只能直接按字符读取。三是SPL扩展库提供的面向对象的fopen()操作。建议在新开发中如果有读取大文件的需求,最好使用这种写法。毕竟SPL函数库已经是PHP了。标准函数库现已面世,面向对象的运行形式更主流。以上三种读取方式需要注意的一点是,我们读取一个大文件后,不要保存在变量中,而应该直接打印显示,放入库或者写入其他文件。因为直接读入变量和前面直接读入内存的方法是一样的,直接修改php.ini的配置,使用top方法直接读入内存就没有那么方便了。还是那句话,把记忆留给真正需要的地方。这么大的文件,最好对硬盘进行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编程实战》各媒体平台均可搜索【硬核项目经理】