PHP读取大文件的几种方法介绍


Posted in PHP onOctober 27, 2016

读取大文件一直是一个头痛的问题,我们像使用php开发读取小文件可以直接使用各种函数实现,但一到大文章就会发现常用的方法是无法正常使用或时间太长太卡了,下面我们就一起来看看关于php读取大文件问题解决办法,希望例子能帮助到各位。

场景:PHP读取超大文件,例如1G的日志文件,我这里使用的是400M的access.log文件

1、使用file直接读取

<?php
$starttime=microtime_float();
 
ini_set('memory_limit', '-1');
$file = 'testfile.txt';
 
$data = file($file);
$line = $data[count($data) - 1000];
$endtime=microtime_float();
 
echo count($data),"<br/>";
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

运行结果:10127784 行   共使用了,7.8764359951s

我的电脑是3G内存,此方法不是推荐使用,因为需要把文件全部载入内存

2、使用linux命令  tail

<?php
 
$starttime=microtime_float();
 
$file = 'testfile.txt';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 100 $file`;
 
echo $line,"<br/>";
 
$endtime=microtime_float();
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
 
//end

运行结果:只使用了几毫秒、轻松搞定、这种方法不能在windows下使用

3、使用fseek函数

这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,因为PHP是C写的,所以实现的时候也类似C读取文件,通过指针的移动,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,

下面是常用的几种方法

方法一:使用fopen打开文件(从文件指针资源句柄)

<?php
$starttime=microtime_float();
 
$file = 'testfile.txt';
$fp = fopen($file, "r+");
 
$line = 100;
$pos = -2;
$t =$data="";
 
while ($line > 0)
{
 while ($t != "\n") //换行符
 {
 fseek($fp, $pos, SEEK_END);//移动指针
 $t = fgetc($fp);//获取一个字符
 $pos--;//向前偏移
 }
 
 $t = "";
 $data = fgets($fp);//获取当前行的数据
 $line--;
}
fclose($fp);
echo $data,"<br/>";
$endtime=microtime_float();
 
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

运行结果:0.338493108749

方法二:一块一块的读取

<?php
$starttime=microtime_float();
 
$file = 'testfile.txt';
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;//4K的块
$fs = sprintf("%u", filesize($file));
$readData='';
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : $fs;
 
for($len = 0; $len < $max; $len += $chunk){
 
 $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len;
 fseek($fp, ($len + $seekSize) * -1, SEEK_END);
 $readData = fread($fp, $seekSize) . $readData;
 
if (substr_count($readData, "\n") >= $num + 1) {
 
 $ns=substr_count($readData, "\n")-$num+2;
 preg_match('/(.*?\n){'.$ns.'}/',$readData,$match);
 $data = $match[1];
 break;
}
}
fclose($fp);
echo $data,"<br/>";
 
 
$endtime=microtime_float();
 
echo $endtime-$starttime;
 
function microtime_float(){
 list($usec, $sec) = explode(" ", microtime());
 return ((float)$usec + (float)$sec);
}
?>

运行时间:0.00199198722839

使用fgets函数,一行一行读取

<?php
$file = fopen("testfile.txt","r");
 while(!feof($file))
 {
   echo fgets($file);
 }
 fclose($file);

spl库函数

<?php
try{
  foreach( new SplFileObject('testfile.txt') as $line)
  echo $line.'<br />';
}catch (Exception $e){
  echo $e->getMessage();
}

另外网上有很多按照块读取文件的,有兴趣的读者可以试试,我试了没成功,好像必须含有换行符“\n”才可以。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP制作图型计数器的例子
Oct 09 PHP
PHP3 safe_mode 失效漏洞
Oct 09 PHP
Session的工作机制详解和安全性问题(PHP实例讲解)
Apr 10 PHP
ThinkPHP表单自动提交验证实例教程
Jul 18 PHP
PHP中创建图像并绘制文字的例子
Nov 19 PHP
微信公众平台消息接口校验与消息接口响应实例
Dec 23 PHP
php $_SESSION会员登录实例分享
Jan 19 PHP
yii2 页面底部加载css和js的技巧
Apr 21 PHP
php 数组元素快速去重
May 05 PHP
php基于数组函数实现关联表的编辑操作示例
Jul 04 PHP
Windows平台PHP+IECapt实现网页批量截图并创建缩略图功能详解
Aug 02 PHP
php提高脚本性能的4个技巧
Aug 18 PHP
php array_multisort 对数组进行排序详解及实例代码
Oct 27 #PHP
PHP中的密码加密的解决方案总结
Oct 26 #PHP
php 解析xml 的四种方法详细介绍
Oct 26 #PHP
PHP 以POST方式提交XML、获取XML,解析XML详解及实例
Oct 26 #PHP
php 生成签名及验证签名详解
Oct 26 #PHP
PHP XML和数组互相转换详解
Oct 26 #PHP
PHP对XML内容进行修改和删除实例代码
Oct 26 #PHP
You might like
php curl_init函数用法
2014/01/31 PHP
Linux下php5.4启动脚本
2014/08/03 PHP
PHP信号处理机制的操作代码讲解
2019/04/19 PHP
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
2006/09/22 Javascript
Jquery显示、隐藏元素以及添加删除样式
2013/08/09 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
jQuery插件Timelinr 实现时间轴特效
2015/10/04 Javascript
js判断登陆用户名及密码是否为空的简单实例
2016/05/16 Javascript
AngularJS服务service用法总结
2016/12/13 Javascript
浅谈JavaScript中promise的使用
2017/01/11 Javascript
JavaScript调试的多个必备小Tips
2017/01/15 Javascript
通过npm或yarn自动生成vue组件的方法示例
2019/02/12 Javascript
浅谈Layui的eleTree树式选择器使用方法
2019/09/25 Javascript
解决vue单页面应用打包后相对路径、绝对路径相关问题
2020/08/14 Javascript
用python处理图片实现图像中的像素访问
2018/05/04 Python
python实现定时提取实时日志程序
2018/06/22 Python
对python3 一组数值的归一化处理方法详解
2018/07/11 Python
解决python 无法加载downsample模型的问题
2018/10/25 Python
python celery分布式任务队列的使用详解
2019/07/08 Python
Python turtle绘画象棋棋盘
2019/08/21 Python
Python 矩阵转置的几种方法小结
2019/12/02 Python
python 装饰器的基本使用
2021/01/13 Python
IE9下html5初试小刀
2010/09/21 HTML / CSS
英国在线泳装店:Simply Swim
2019/05/05 全球购物
现代化办公人员工作的自我评价
2013/10/16 职场文书
我们的节日端午节活动方案
2014/03/02 职场文书
演讲稿格式
2014/04/30 职场文书
学校学习雷锋活动总结
2014/07/03 职场文书
公司委托书格式范本
2014/09/16 职场文书
2014年法制宣传日活动方案
2014/11/02 职场文书
酒店优秀员工推荐信
2015/03/24 职场文书
医院感染管理制度
2015/08/05 职场文书
2016优秀青年志愿者事迹材料
2016/02/25 职场文书
numpy数据类型dtype转换实现
2021/04/24 Python
Python基于Opencv识别两张相似图片
2021/04/25 Python
Python批量解压&压缩文件夹的示例代码
2022/04/04 Python