PHP大文件读取操作

时间:2021-01-11 03:35:26

简单的文件读取,一般我们会使用 file_get_contents() 这类方式来直接获取文件的内容。不过这种函数有个严重的问题是它会把文件一次性地加载到内存中,也就是说,它会受到内存的限制。因此,加载大文件的时候是绝对不能使用这种方式的。我们还是先看看这种方式加载的例子。

// 普通的文件读取 一个2.4G的SQL导出文件
$fileName= './2020-02-23.sql'; // file_get_contents
$fileInfo = file_get_contents($fileName);
// Fatal error: Allowed memory size of 134217728 bytes exhausted // file
$fileInfo = file($fileName);
// Fatal error: Allowed memory size of 134217728 bytes exhausted // fopen + fread
$fileHandle = fopen($fileName, 'r');
$fileInfo = fread($fileHandle, filesize($fileName));
// Fatal error: Allowed memory size of 134217728 bytes exhausted

上述三种形式的文件加载读取方式都是不能加载这么大的文件的,当然,你也可以修改 php.ini 中的相关配置让他们能够加载成功,但我们并不推荐这样使用,毕竟内存资源相比硬盘资源还是要宝贵的多。

以下的方式是可以直接读取这种大文件的:

// readfile 只能直接输出
echo readfile($fileName); // fopen + fgetc 如果单
$fileHandle = fopen($fileName, 'r');
// 输出单字符直到 end-of-file
while(!feof($fileHandle)) {
echo fgetc($fileHandle);
}
fclose($fileHandle); // SplFileObject
$fileObject = new SplFileObject($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编程实战》

PHP大文件读取操作的更多相关文章

  1. day08 学习小测试 九九乘法表 车牌划分计算 大文件读取操作

    1.1需求:读取一个100G的文件,检测文件中是否有关键字keys=['苍老师','小泽老师',"alex"], 如果有则替换成"***",并写入到另一个文件中 ...

  2. linux大文件读取

    在生产环境中有时候可能会遇到大文件的读取问题,但是大文件读取如果按照一般的手法.如cat这种都是对io的一个挑战,如果io扛得住还好,如果扛不住 造成的后果,如服务器内存奔溃,日志损坏 方法一: se ...

  3. Perl中文件读取操作

    Perl中文件读取操作 http://blog.csdn.net/yangxuan12580/article/details/51506216

  4. python大文件读取

    python大文件读取 https://*.com/questions/8009882/how-to-read-a-large-file-line-by-line-in-pyt ...

  5. TCP协议传输大文件读取时候的问题

    TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...

  6. Java解决大文件读取的内存问题以及文件流的比较

    Java解决大文件读取的内存问题以及文件流的比较 传统方式 读取文件的方式一般是是从内存中读取,官方提供了几种方式,如BufferedReader, 以及InputStream 系列的,也有封装好的如 ...

  7. 大文件读取方法(C#)

    之前都是用StreamReader.ReadLine方法逐行读取文件,自从.NET4有了File.ReadLines这一利器,就再也不用为大文件发愁了. File.ReadLines在整个文件读取到内 ...

  8. 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射

    内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码.fileC ...

  9. C基础 大文件读取通过标准库

    引言 - 问题的构建 C大部分读取文件的时候采用fgetc, 最近在使用过程中发现性能不是很理想.都懂得fgetc每次只能读取一个字符, IO操作太频繁. 所以性能低. 本文希望通过标准库函数frea ...

随机推荐

  1. Linux挂载磁盘

    查看 fdisk –l 挂载 mount 磁盘 目录 参考地址:http://blog.csdn.net/tianlesoftware/article/details/5642883 卸载 umoun ...

  2. jquery基本方法

    jquery的delay sleep 与js的setTime的区别. delay 和sleep推荐不要用,太难用了. click on live delegate bind http://www.jb ...

  3. koa 笔记 运行错误

    按照 演示的代码 直接运行会出错,大家需要调整方式. http://koajs.cn/ 要安装以下 $ npm install -g n$ n 0.11.12$ node --harmony my-k ...

  4. css.day03

    css的分类(位置): css层叠样式表 1.内嵌 样式表 2.行内样式表 3. 外连 css选择器分类 基础选择器 标签 id选择器 类选择器 复合选择器 交集选择器(标签指定式)  span.on ...

  5. 黑马程序员_Java基本数据类型对象包装类

    基本数据类型对象包装类 byte Byte short Short int Integer long Long boolean Boolean float Float double Double ch ...

  6. Codeforces 372B Counting Rectangles is Fun

    http://codeforces.com/problemset/problem/372/B 题意:每次给出一个区间,求里面有多少个矩形 思路:预处理,sum[i][j][k][l]代表以k,l为右下 ...

  7. LeakCanary,检测安卓,java内存泄漏

    官方中文API地址:http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/

  8. Android-管理Activity生命周期 -停止和重启Activity

    停止和重启activity在activity的生命周期中很重要,它能让用户感觉你的app总是激活的而且不会丢失他们的进度.activity在下面的这些情况会停止和重启: 用户打开常用app窗口然后从你 ...

  9. 路由知识 静态路由 rip eigrp ospf

    第1章 路由选择原理 1.1 几个概念 1.1.1 被动路由协议 用来在路由之间传递用户信息 1.1.2 主动路由协议 用于维护路由器的路由表 R2#show ip route Codes: C - ...

  10. Page Object设计模式实践

    Page Object模式是使用Selenium的广大同行最为公认的一种设计模式.在设计测试时,把元素和方法按照页面抽象出来,分离成一定的对象,然后再进行组织. Page Object模式,创建一个对 ...