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 相关文章推荐
WINDOWS服务器安装多套PHP的另类解决方案
Oct 09 PHP
php中将数组存到文件里的实现代码
Jan 19 PHP
php中0,null,empty,空,false,字符串关系的详细介绍
Jun 20 PHP
php 验证码(倾斜,正弦干扰线,黏贴,旋转)
Jun 29 PHP
百度ping方法使用示例 自动ping百度
Jan 26 PHP
PHP获取QQ达人QQ信息的方法
Mar 05 PHP
ThinkPHP3.2.3实现分页的方法详解
Jun 03 PHP
ThinkPHP框架表单验证操作方法
Jul 19 PHP
swoole和websocket简单聊天室开发
Nov 18 PHP
详解Yaf框架PHPUnit集成测试方法
Dec 27 PHP
PHP session垃圾回收机制实例分析
Jun 28 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
Apr 05 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安装问题
2006/10/09 PHP
Windows下的PHP5.0详解
2006/11/18 PHP
php计算税后工资的方法
2015/07/28 PHP
微信公众号OAuth2.0网页授权问题浅析
2017/01/21 PHP
PHP两个n位的二进制整数相加问题的解决
2018/08/26 PHP
PHP登录验证功能示例【用户名、密码、验证码、数据库、已登陆验证、自动登录和注销登录等】
2019/02/25 PHP
Thinkphp整合阿里云OSS图片上传实例代码
2019/04/28 PHP
JavaScript去除空格的几种方法
2006/10/03 Javascript
JS location几个方法小姐
2008/07/09 Javascript
关于viewport,Ext.panel和Ext.form.panel的关系
2009/05/07 Javascript
cnblogs 代码高亮显示后的代码复制问题解决实现代码
2011/12/14 Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
2013/05/17 Javascript
JavaScript的strict模式与with关键字介绍
2014/02/08 Javascript
ECMAScript6轮播图实践知识总结
2016/08/17 Javascript
AngularJS中的promise用法分析
2017/05/19 Javascript
Angular表格神器ui-grid应用详解
2017/09/29 Javascript
Vue 使用beforeEach实现登录状态检查功能
2019/10/31 Javascript
JS实现音乐钢琴特效
2020/01/06 Javascript
vue3 watch和watchEffect的使用以及有哪些区别
2021/01/26 Vue.js
[40:31]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python连接SQLServer2000的方法详解
2017/04/19 Python
python3爬取淘宝信息代码分析
2018/02/10 Python
pandas 快速处理 date_time 日期格式方法
2018/11/12 Python
Python enumerate函数功能与用法示例
2019/03/01 Python
如何通过命令行进入python
2020/07/06 Python
用HTML5制作一个简单的弹力球游戏
2015/05/12 HTML / CSS
eVitamins日本:在线购买折扣维生素、补品和草药
2019/04/04 全球购物
Oasis服装官网:时尚女装在线
2020/07/09 全球购物
介绍一下Python中webbrowser的用法
2013/05/07 面试题
四年的大学生生活自我评价
2013/12/09 职场文书
《花木兰》教学反思
2014/04/09 职场文书
尊老爱幼演讲稿
2014/09/04 职场文书
民主生活会批评与自我批评总结
2014/10/17 职场文书
小学庆六一主持词
2015/06/30 职场文书
详解 TypeScript 枚举类型
2021/11/02 Javascript
Python实现批量自动整理文件
2022/03/16 Python