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
php checkdate、getdate等日期时间函数操作详解
Mar 11 PHP
PHP之数组学习
May 29 PHP
php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系
Nov 02 PHP
ThinkPHP CURD方法之data方法详解
Jun 18 PHP
thinkphp常见路径用法分析
Dec 02 PHP
php获取四位字母和数字的随机数的实现方法
Jan 09 PHP
curl和libcurl的区别简介
Jul 01 PHP
PHP中常用的数组操作方法笔记整理
May 16 PHP
浅谈thinkphp5 instance 的简单实现
Jul 30 PHP
PHP获取数组中指定的一列实例
Dec 27 PHP
tp5框架基于ajax实现异步删除图片的方法示例
Feb 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下对字符串的递增运算代码
2010/08/21 PHP
浅析Mysql 数据回滚错误的解决方法
2013/08/05 PHP
Yii2中YiiBase自动加载类、引用文件方法分析(autoload)
2016/07/25 PHP
js几个不错的函数 $$()
2006/10/09 Javascript
javascript 程序库的比较(一)之DOM功能
2010/04/07 Javascript
js中apply方法的使用详细解析
2013/11/04 Javascript
Iframe 自动适应页面的高度示例代码
2014/02/26 Javascript
JavaScript数据类型检测代码分享
2015/01/26 Javascript
JS实现的论坛Ajax打分效果完整实例
2015/10/31 Javascript
解决JavaScript数字精度丢失问题的方法
2015/12/03 Javascript
AngularJS中关于ng-class指令的几种实现方式详解
2016/09/17 Javascript
Angular4 中常用的指令入门总结
2017/06/12 Javascript
聊聊Vue.js的template编译的问题
2017/10/09 Javascript
js实现简单选项卡功能
2020/03/23 Javascript
详解Vue.js iview实现树形权限表(可扩展表)
2018/09/30 Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
2020/07/28 Javascript
微信小程序轮播图swiper代码详解
2020/12/01 Javascript
vuex页面刷新导致数据丢失的解决方案
2020/12/10 Vue.js
[57:38]2018DOTA2亚洲邀请赛3月30日 小组赛A组 OpTic VS OG
2018/03/31 DOTA
pyqt4教程之widget使用示例分享
2014/03/07 Python
python导入csv文件出现SyntaxError问题分析
2017/12/15 Python
Python登录并获取CSDN博客所有文章列表代码实例
2017/12/28 Python
详解Django+Uwsgi+Nginx 实现生产环境部署
2018/11/06 Python
使用Python 正则匹配两个特定字符之间的字符方法
2018/12/24 Python
TensorFlow:将ckpt文件固化成pb文件教程
2020/02/11 Python
django 解决自定义序列化返回处理数据为null的问题
2020/05/20 Python
python 装饰器的使用示例
2020/10/10 Python
Vs Code中8个好用的python 扩展插件
2020/10/12 Python
Python 操作SQLite数据库的示例
2020/10/16 Python
Python爬虫逆向分析某云音乐加密参数的实例分析
2020/12/04 Python
美体小铺加拿大官方网站:The Body Shop加拿大
2016/10/30 全球购物
机电专业体育教师求职信
2013/09/21 职场文书
仓库理货员岗位职责
2013/12/18 职场文书
促销活动计划书
2014/05/02 职场文书
学习三严三实心得体会
2014/10/13 职场文书
python for循环赋值问题
2021/06/03 Python