PHP大文件读取操作
简单的文件读取,一般我们会使用 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操作。
参考文档:
《PHP7编程实战》
PHP大文件读取操作的更多相关文章
- day08 学习小测试 九九乘法表 车牌划分计算 大文件读取操作
1.1需求:读取一个100G的文件,检测文件中是否有关键字keys=['苍老师','小泽老师',"alex"], 如果有则替换成"***",并写入到另一个文件中 ...
- linux大文件读取
在生产环境中有时候可能会遇到大文件的读取问题,但是大文件读取如果按照一般的手法.如cat这种都是对io的一个挑战,如果io扛得住还好,如果扛不住 造成的后果,如服务器内存奔溃,日志损坏 方法一: se ...
- Perl中文件读取操作
Perl中文件读取操作 http://blog.csdn.net/yangxuan12580/article/details/51506216
- python大文件读取
python大文件读取 https://stackoverflow.com/questions/8009882/how-to-read-a-large-file-line-by-line-in-pyt ...
- TCP协议传输大文件读取时候的问题
TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...
- Java解决大文件读取的内存问题以及文件流的比较
Java解决大文件读取的内存问题以及文件流的比较 传统方式 读取文件的方式一般是是从内存中读取,官方提供了几种方式,如BufferedReader, 以及InputStream 系列的,也有封装好的如 ...
- 大文件读取方法(C#)
之前都是用StreamReader.ReadLine方法逐行读取文件,自从.NET4有了File.ReadLines这一利器,就再也不用为大文件发愁了. File.ReadLines在整个文件读取到内 ...
- 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射
内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码.fileC ...
- C基础 大文件读取通过标准库
引言 - 问题的构建 C大部分读取文件的时候采用fgetc, 最近在使用过程中发现性能不是很理想.都懂得fgetc每次只能读取一个字符, IO操作太频繁. 所以性能低. 本文希望通过标准库函数frea ...
随机推荐
- JVM学习笔记-第七章-虚拟机类加载机制
JVM学习笔记-第七章-虚拟机类加载机制 7.1 概述 Java虚拟机描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被 ...
- CVE-2021-1732 Windows 本地权限提升漏洞 EXP 下载
漏洞简介 2021年2月10日,微软修复了一个Windows本地权限提升漏洞,漏洞编号为 CVE-2021-1732 ,本地攻击者可以利用该漏洞将权限提升为 System ,目前EXP已公开. 影响范 ...
- DVWA靶场之File Upload(文件上传)通关
Low: <?php if( isset( $_POST[ 'Upload' ] ) ) { // Where are we going to be writing to? $target_pa ...
- 基于kail的docker下安装sqli-labs
后面的关卡涉及到转码问题,比如空格,在Windows中会受到限制,比如24关的文件重命名问题,所以在这记录下在docker下安装sqli-labs,在linux下运行就不会受到限制. 参考链接:htt ...
- noip37
为何我对T3情有独钟 T1 不难发现,题目要求的就是 \(ax+by=c\) ,已知 \(a,b,c\) ,求 \(\min\{|a|+|b|\}\) ,那就用扩欧求一组特解,再分情况讨论即可. Co ...
- 题解 string
传送门 考试的时候只来得及糊了个\(n^4\)的暴力,结果考完发现\(n^2\)比\(n^4\)还好写 题意就是就是要求把一堆字符串的前后缀拼起来之后在原串中出现了多少次 然而前后缀可以有很多,再枚举 ...
- luoguP1528&2329 栅栏&切蛋糕
前言 蒟弱本来是在亿万年前做二分答案专题栅栏的,由于数据水所以过掉了,后来发现有一个数据加强版,也就是本题,于是爆T了...过了有个五六个月回来填坑了...现在开O2是在最优解第一个(自豪ing 题目 ...
- ubuntu20.04 apache2 配置安装ssl证书
1. 获取SSL证书 根据自己的网站服务器来获取不同的ssl证书,我的服务器是ubuntu20.04. 证书如下: 00_***.key ## 私钥文件 01_CERTIFICATE_***_***. ...
- 手把手教你AspNetCore WebApi:Swagger(Api文档)
前言 小明已经实现"待办事项"的增删改查,并美滋滋向负责前端的小红介绍Api接口,小红很忙,暂时没有时间听小明介绍,希望小明能给个Api文档.对于码农小明来说能不写文档就尽量不要写 ...
- Longhorn 云原生容器分布式存储 - Air Gap 安装
内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生容器分布式存储 - 设计架构和概念 Longhorn 云原生容器分布式存储 - ...