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 相关文章推荐
PHP5+UTF8多文件上传类
Oct 17 PHP
php实现的遍历文件夹下所有文件,编辑删除
Jan 05 PHP
纯php打造的tab选项卡效果代码(不用js)
Dec 29 PHP
php设计模式 Strategy(策略模式)
Jun 26 PHP
PHP简洁函数(PHP简单明了函数语法)
Jun 10 PHP
有关PHP性能优化的介绍
Jun 20 PHP
PHP防止注入攻击实例分析
Nov 03 PHP
Dwz与thinkphp整合下的数据导出到Excel实例
Dec 04 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
Mar 07 PHP
PHP编程实现微信企业向用户付款的方法示例
Jul 26 PHP
laravel-admin的多级联动方法
Sep 30 PHP
Thinkphp 框架扩展之驱动扩展实例分析
Apr 27 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 图片上传代码
2011/09/13 PHP
thinkphp3查询mssql数据库乱码解决方法分享
2014/02/11 PHP
PHP中substr_count()函数获取子字符串出现次数的方法
2016/01/07 PHP
php组合排序简单实现方法
2016/10/15 PHP
PHP登录(ajax提交数据和后台校验)实例分享
2016/12/29 PHP
用 JavaScript 迁移目录
2006/12/18 Javascript
使弱类型的语言JavaScript变强势
2009/06/22 Javascript
Dojo 学习要点
2010/09/03 Javascript
jquery操作checked属性以及disabled属性的多种方法
2014/06/20 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
在JavaScript中处理时间之getHours()方法的使用
2015/06/10 Javascript
javascript创建对象的几种模式介绍
2016/05/06 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
VueJs 将接口用webpack代理到本地的方法
2017/11/27 Javascript
JavaScript 2018 中即将迎来的新功能
2018/09/21 Javascript
jQuery轻量级表单模型验证插件
2018/10/15 jQuery
原生JavaScript实现留言板
2021/01/10 Javascript
python执行shell获取硬件参数写入mysql的方法
2014/12/29 Python
Python中字符串的格式化方法小结
2016/05/03 Python
python实现图书管理系统
2018/03/12 Python
python计算无向图节点度的实例代码
2019/11/22 Python
在python中logger setlevel没有生效的解决
2020/02/21 Python
利用Python制作动态排名图的实现代码
2020/04/09 Python
Pycharm如何导入python文件及解决报错问题
2020/05/10 Python
keras用auc做metrics以及早停实例
2020/07/02 Python
整理HTML5的一些新特性与Canvas的常用属性
2016/01/29 HTML / CSS
施工资料员的岗位职责
2013/12/22 职场文书
中专生职业生涯规划书范文
2014/01/10 职场文书
中学教师自我鉴定
2014/02/07 职场文书
党校培训自我鉴定范文
2014/04/10 职场文书
职业生涯规划书结束语
2014/04/15 职场文书
协议书模板
2014/04/23 职场文书
基层干部个人对照检查及整改措施
2014/10/28 职场文书
MySQL 1130异常,无法远程登录解决方案详解
2021/08/23 MySQL
pandas中pd.groupby()的用法详解
2022/06/16 Python