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 相关文章推荐
用文本文件实现的动态实时发布新闻的程序
Oct 09 PHP
PHP form 表单传参明细研究
Jul 17 PHP
PHP新手用的Insert和Update语句构造类
Mar 31 PHP
Smarty的配置与高级缓存技术分享
Jun 05 PHP
PHP中通过fopen()函数访问远程文件示例
Nov 18 PHP
php 在线导入mysql大数据程序
Jun 11 PHP
10个超级有用的PHP代码片段果断收藏
Sep 23 PHP
mac系统下为 php 添加 pcntl 扩展
Aug 28 PHP
php 二维数组时间排序实现代码
Nov 19 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
Mar 31 PHP
PDO::errorInfo讲解
Jan 28 PHP
mysqli扩展无法在PHP7下升级问题的解决
Sep 10 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集成FCK的函数代码
2008/09/27 PHP
如何使用Linux的Crontab定时执行PHP脚本的方法
2011/12/19 PHP
php定界符
2014/06/19 PHP
PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例
2014/07/15 PHP
PHP变量的作用范围实例讲解
2020/12/22 PHP
用JavaScript仿PS里的羽化效果代码
2011/12/20 Javascript
jQuery实现回车键(Enter)切换文本框焦点的代码实例
2014/05/05 Javascript
Jquery实现仿腾讯娱乐频道焦点图(幻灯片)特效
2015/03/06 Javascript
jQuery+jsp实现省市县三级联动效果(附源码)
2015/12/03 Javascript
AngularJS表格详解及示例代码
2016/08/17 Javascript
Nodejs进阶:核心模块net入门学习与实例讲解
2016/11/21 NodeJs
js实现上下左右弹框划出效果
2017/03/08 Javascript
Vue Echarts实现可视化世界地图代码实例
2019/05/07 Javascript
让 babel webpack vue 配置文件支持智能提示的方法
2019/06/22 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
2020/08/17 Javascript
[55:47]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第三局
2016/02/27 DOTA
Python解析nginx日志文件
2015/05/11 Python
让python在hadoop上跑起来
2016/01/27 Python
Django Highcharts制作图表
2016/08/27 Python
pandas apply 函数 实现多进程的示例讲解
2018/04/20 Python
Python叠加两幅栅格图像的实现方法
2019/07/05 Python
python3-flask-3将信息写入日志的实操方法
2019/11/12 Python
TensorFlow2.0矩阵与向量的加减乘实例
2020/02/07 Python
Python任务调度利器之APScheduler详解
2020/04/02 Python
基于python实现生成指定大小txt文档
2020/07/20 Python
史上最全面的Java面试题汇总!
2015/02/03 面试题
大四自我鉴定范文
2013/10/06 职场文书
大学生村官心得体会范文
2014/01/04 职场文书
高校教师自荐信范文
2014/03/13 职场文书
临床医师个人自我评价
2014/04/06 职场文书
会员活动策划方案
2014/08/19 职场文书
大学毕业典礼演讲稿
2014/09/09 职场文书
生活小常识广播稿
2014/09/16 职场文书
CSS实现多个元素在盒子内两端对齐效果
2021/03/30 HTML / CSS
Pandas数据结构之Series的使用
2022/03/31 Python
Vue OpenLayer测距功能的实现
2022/04/20 Vue.js