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 db类库进行数据库操作
Mar 19 PHP
抓取并下载CSS中所有图片文件的php代码
Sep 26 PHP
解析php框架codeigniter中如何使用框架的session
Jun 24 PHP
PHP的password_hash()使用实例
Mar 17 PHP
在PHP中使用X-SendFile头让文件下载更快
Jun 01 PHP
php实现的zip文件内容比较类
Sep 24 PHP
apache中为php 设置虚拟目录
Dec 17 PHP
举例讲解PHP面对对象编程的多态
Aug 12 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
Sep 22 PHP
Yii CFileCache 获取不到值的原因分析
Feb 08 PHP
Thinkphp5.0 框架Model模型简单用法分析
Oct 11 PHP
PHP函数用法详解【初始化、嵌套、内置函数等】
Jun 02 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
如何让thinkphp在模型中自动完成session赋值小教程
2014/09/05 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
PHP dirname简单使用代码实例
2020/11/13 PHP
javascript第一课
2007/02/27 Javascript
JavaScript动态创建form表单并提交的实现方法
2015/12/10 Javascript
探析浏览器执行JavaScript脚本加载与代码执行顺序
2016/01/12 Javascript
Ajax实现不刷新取最新商品
2017/03/01 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
jQuery常见面试题之DOM操作详析
2017/07/05 jQuery
JavaScript实现的浏览器下载文件的方法
2017/08/09 Javascript
基于vue中css预加载使用sass的配置方式详解
2018/03/13 Javascript
在vue中使用jointjs的方法
2018/03/24 Javascript
layui table 多行删除(id获取)的方法
2019/09/12 Javascript
Vue执行方法,方法获取data值,设置data值,方法传值操作
2020/08/05 Javascript
Python导入txt数据到mysql的方法
2015/04/08 Python
Python中输出ASCII大文字、艺术字、字符字小技巧
2015/04/28 Python
python图片验证码生成代码
2016/07/02 Python
django+js+ajax实现刷新页面的方法
2017/05/22 Python
Python使用Tkinter实现机器人走迷宫
2018/01/22 Python
Python 使用PIL numpy 实现拼接图片的示例
2018/05/08 Python
flask-socketio实现WebSocket的方法
2018/07/31 Python
python自动发邮件总结及实例说明【推荐】
2019/05/31 Python
django实现支付宝支付实例讲解
2019/10/17 Python
Python 依赖库太多了该如何管理
2019/11/08 Python
Python 2.6.6升级到Python2.7.15的详细步骤
2020/12/14 Python
python压包的概念及实例详解
2021/02/17 Python
汽车技术服务与营销专业在籍生自荐信
2013/09/28 职场文书
专科毕业生学习生活的自我评价
2013/10/26 职场文书
副厂长岗位职责
2014/02/02 职场文书
《中彩那天》教学反思
2014/02/22 职场文书
2014年党员公开承诺践诺书
2014/03/25 职场文书
庆元旦主持词
2015/07/06 职场文书
2015年评职称个人工作总结
2015/10/15 职场文书
多人股份制合作协议书
2016/03/19 职场文书
2017年寒假少先队活动总结
2016/04/06 职场文书
CSS3 制作的书本翻页特效
2021/04/13 HTML / CSS