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 函数语法介绍一
Jun 14 PHP
PHP 数据结构 算法 三元组 Triplet
Jul 02 PHP
简单的php写入数据库类代码分享
Jul 26 PHP
php操作mysql数据库的基本类代码
Feb 25 PHP
php中的字符编码转换函数用法示例
Oct 20 PHP
PHP如何实现Unicode和Utf-8编码相互转换
Jul 29 PHP
PHP连接MSSQL方法汇总
Feb 05 PHP
PHP count()函数讲解
Feb 03 PHP
Laravel 将数据表的数据导出,并生成seeds种子文件的方法
Oct 09 PHP
tp5框架前台无限极导航菜单类实现方法分析
Mar 29 PHP
详解使用php-cs-fixer格式化代码
Sep 16 PHP
MacOS下PHP7.1升级到PHP7.4.15的方法
Feb 22 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 IN_ARRAY 函数使用注意事项
2010/07/24 PHP
PHP游戏编程25个脚本代码
2011/02/08 PHP
php学习之function的用法
2012/07/14 PHP
php像数组一样存取和修改字符串字符
2014/03/21 PHP
Yii2实现自定义独立验证器的方法
2017/05/05 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
javascript动态修改Li节点值的方法
2015/01/20 Javascript
基于Bootstrap重置输入框内容按钮插件
2016/05/12 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
2016/08/17 Javascript
js实现目录链接,内容跟着目录滚动显示的简单实例
2016/10/15 Javascript
前端开发必知的15个jQuery小技巧
2017/01/22 Javascript
利用javascript实现的三种图片放大镜效果实例(附源码)
2017/01/23 Javascript
JavaScript该如何学习 怎样轻松学习JavaScript
2017/06/12 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
JS函数进阶之继承用法实例分析
2020/01/15 Javascript
JS实现电脑虚拟键盘打字测试
2020/06/24 Javascript
微信小程序拖拽排序列表的示例代码
2020/07/08 Javascript
如何在Vue中使localStorage具有响应式(思想实验)
2020/07/14 Javascript
[41:52]2018DOTA2亚洲邀请赛3月29日 小组赛A组 TNC VS OpTic
2018/03/30 DOTA
自己编程中遇到的Python错误和解决方法汇总整理
2015/06/03 Python
Python中functools模块的常用函数解析
2016/06/30 Python
解决python文件字符串转列表时遇到空行的问题
2017/07/09 Python
Python爬虫抓取代理IP并检验可用性的实例
2018/05/07 Python
Pytorch evaluation每次运行结果不同的解决
2020/01/02 Python
python TCP包注入方式
2020/05/05 Python
keras实现多种分类网络的方式
2020/06/11 Python
CSS3媒体查询Media Queries基础学习教程
2016/02/29 HTML / CSS
亚洲最大旅游体验平台:KKday
2017/10/21 全球购物
卡西欧G-SHOCK英国官网: 防水防震手表
2018/01/08 全球购物
易程科技软件测试笔试
2013/03/24 面试题
关于打架的检讨书
2014/01/17 职场文书
运动会广播稿30字
2014/01/21 职场文书
入党介绍人意见范文
2015/06/01 职场文书
2016教师校本培训心得体会
2016/01/08 职场文书
win11如何查看端口是否被占用? Win11查看端口是否占用的技巧
2022/04/05 数码科技
Python自动化实战之接口请求的实现
2022/05/30 Python