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 similar_text 字符串的相似性比较函数
May 26 PHP
PHP XML error parsing SOAP payload on line 1
Jun 17 PHP
ecshop 批量上传(加入自定义属性)
Mar 20 PHP
关于js与php互相传值的介绍
Jun 25 PHP
PHP函数http_build_query使用详解
Aug 20 PHP
php根据某字段对多维数组进行排序的方法
Mar 07 PHP
PHP生成唯一订单号
Jul 05 PHP
php链表用法实例分析
Jul 09 PHP
php简单防盗链实现方法
Jul 29 PHP
php 函数使用可变数量的参数方法
May 02 PHP
在 Laravel 6 中缓存数据库查询结果的方法
Dec 11 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
PHP4与PHP5的时间格式问题
2008/02/17 PHP
在PHP中读取和写入WORD文档的代码
2008/04/09 PHP
PHP积分兑换接口实例
2015/02/09 PHP
避免Smarty与CSS语法冲突的方法
2015/03/02 PHP
实例详解PHP中html word 互转的方法
2016/01/28 PHP
PHP pear安装配置教程
2016/05/14 PHP
php解析xml 的四种简单方法(附实例)
2016/07/11 PHP
PHP支付宝当面付2.0代码
2018/12/21 PHP
JS 无限级 Select效果实现代码(json格式)
2011/08/30 Javascript
jQuery对下拉框,单选框,多选框的操作
2014/02/21 Javascript
nodejs实现获取某宝商品分类
2015/05/28 NodeJs
js实现带有介绍的Select列表菜单实例
2015/08/18 Javascript
js实现无限级树形导航列表效果代码
2015/09/23 Javascript
javascript针对cookie的基本操作实例详解
2015/11/30 Javascript
原生JS封装ajax 传json,str,excel文件上传提交表单(推荐)
2016/06/21 Javascript
很实用的js选项卡切换效果
2016/08/12 Javascript
简单的渐变轮播插件
2017/01/12 Javascript
Javascript面试经典套路reduce函数查重
2017/03/23 Javascript
JS闭包可被利用的常见场景小结
2017/04/09 Javascript
jquery层次选择器的介绍
2019/01/18 jQuery
Vue项目使用localStorage+Vuex保存用户登录信息
2019/05/27 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
2019/11/09 Javascript
vue编写简单的购物车功能
2021/01/08 Vue.js
[01:26]神话结束了,却也刚刚开始——DOTA2新英雄玛尔斯驾临战场
2019/03/10 DOTA
Python连接phoenix的方法示例
2017/09/29 Python
Python3.5常见内置方法参数用法实例详解
2019/04/29 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
2019/06/18 Python
Centos7 下安装最新的python3.8
2019/10/28 Python
24个canvas基础知识小结
2014/12/17 HTML / CSS
编写类String的构造函数、析构函数和赋值函数
2012/05/29 面试题
幼儿教师师德演讲稿
2014/05/06 职场文书
Python-OpenCV实现图像缺陷检测的实例
2021/06/11 Python
MySQL 十大常用字符串函数详解
2021/06/30 MySQL
Java后端 Dubbo retries 超时重试机制的解决方案
2022/04/14 Java/Android
python开发制作好看的时钟效果
2022/05/02 Python
canvas 中如何实现物体的框选
2022/08/05 Javascript