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巧获服务器端信息
Dec 06 PHP
php中iconv函数使用方法
May 24 PHP
PHP mail 通过Windows的SMTP发送邮件失败的解决方案
May 27 PHP
discuz7 phpMysql操作类
Jun 21 PHP
过滤掉PHP数组中的重复值的实现代码
Jul 17 PHP
从零开始学YII2框架(六)高级应用程序模板
Aug 20 PHP
Yii实现单用户博客系统文章详情页插入评论表单的方法
Dec 28 PHP
Yii控制器中操作视图js的方法
Jul 04 PHP
降低PHP Redis内存占用
Mar 23 PHP
PHP获取文本框、密码域、按钮的值实例代码
Apr 19 PHP
laravel 事件/监听器实例代码
Apr 12 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
Feb 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
9个PHP开发常用功能函数小结
2011/07/15 PHP
7个鲜为人知却非常实用的PHP函数
2015/07/01 PHP
Zend Framework动作助手FlashMessenger用法详解
2016/03/05 PHP
如果文字过长,则将过长的部分变成省略号显示
2006/06/26 Javascript
javascript 读取图片文件的大小
2009/06/25 Javascript
juqery 学习之六 CSS--css、位置、宽高
2011/02/11 Javascript
JS操作JSON要领详细总结
2013/08/25 Javascript
使用Plupload实现直接上传附件至七牛云存储
2014/12/26 Javascript
js判断图片加载完成后获取图片实际宽高的方法
2016/02/25 Javascript
表单中单选框添加选项和移除选项
2016/07/04 Javascript
Jil,高效的json序列化和反序列化库
2017/02/15 Javascript
浅谈react.js中实现tab吸顶效果的问题
2017/09/06 Javascript
BACKBONE.JS 简单入门范例
2017/10/17 Javascript
JavaScript实现QQ列表展开收缩扩展功能
2017/10/30 Javascript
vue2.0在table中实现全选和反选的示例代码
2017/11/04 Javascript
如何快速解决JS或Jquery ajax异步跨域的问题
2018/01/08 jQuery
Nuxt.js踩坑总结分享
2018/01/18 Javascript
Vue的事件响应式进度条组件实例详解
2018/02/04 Javascript
浅谈Vue 数据响应式原理
2018/05/07 Javascript
微信小程序实现图片上传功能
2018/05/28 Javascript
解决Layui当中的导航条动态添加后渲染失败的问题
2019/09/25 Javascript
JavaScript对象字面量和构造函数原理与用法详解
2020/04/18 Javascript
Python中文分词实现方法(安装pymmseg)
2016/06/14 Python
在双python下设置python3为默认的方法
2018/10/31 Python
Python爬取破解无线网络wifi密码过程解析
2019/09/17 Python
Python tkinter三种布局实例详解
2020/01/06 Python
详解Python中的分支和循环结构
2020/02/11 Python
Django 设置多环境配置文件载入问题
2020/02/25 Python
HTML5 embed标签定义和用法详解
2014/05/09 HTML / CSS
美国领先的家庭健康检测试剂盒提供商:LetsGetChecked
2019/03/18 全球购物
小学生环保演讲稿
2014/04/25 职场文书
地质工程专业毕业生求职信
2014/08/08 职场文书
六年级语文下册教学计划
2015/01/22 职场文书
老干部座谈会主持词
2015/07/03 职场文书
保险公司岗前培训工作总结
2015/10/24 职场文书
Java常用函数式接口总结
2021/06/29 Java/Android