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 相关文章推荐
js下函数般调用正则的方法附代码
Jun 22 PHP
php在线打包程序源码
Jul 27 PHP
PHP ajax 分页类代码
Nov 13 PHP
探讨如何把session存入数据库
Jun 07 PHP
php 根据url自动生成缩略图并处理高并发问题
Jan 23 PHP
采用memcache在web集群中实现session的同步会话
Jul 05 PHP
destoon供应信息title调用出公司名称的方法
Aug 22 PHP
php基于表单密码验证与HTTP验证用法实例
Jan 06 PHP
php实现的简单日志写入函数
Mar 31 PHP
php准确获取文件MIME类型的方法
Jun 17 PHP
Yii2框架自定义验证规则操作示例
Feb 08 PHP
PHP实现与java 通信的插件使用教程
Aug 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
如何对PHP程序中的常见漏洞进行攻击(上)
2006/10/09 PHP
浅析PHP 按位与或 (^ 、&amp;)
2013/06/21 PHP
php中in_array函数用法探究
2014/11/25 PHP
简单谈谈 php 文件锁
2017/02/19 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
javascript 事件处理、鼠标拖动效果实现方法详解
2012/05/11 Javascript
JQuery实现鼠标移动到图片上显示边框效果
2014/01/09 Javascript
对JavaScript的全文搜索实现相关度评分的功能的方法
2015/06/24 Javascript
jquery实现表单验证并阻止非法提交
2015/07/09 Javascript
jQuery实现鼠标点击弹出渐变层的方法
2015/07/09 Javascript
javascript中substring()、substr()、slice()的区别
2015/08/30 Javascript
jQuery实用技巧必备(中)
2015/11/03 Javascript
jquery ztree实现树的搜索功能
2016/02/25 Javascript
Bootstrap CSS布局之列表
2016/12/15 Javascript
仿iPhone通讯录制作小程序自定义选择组件的实现
2019/05/23 Javascript
JavaScript实现随机五位数验证码
2019/09/27 Javascript
python使用mailbox打印电子邮件的方法
2015/04/30 Python
Python实现将doc转化pdf格式文档的方法
2018/01/19 Python
Python+matplotlib绘制不同大小和颜色散点图实例
2018/01/19 Python
使用Python横向合并excel文件的实例
2018/12/11 Python
python实现ip地址查询经纬度定位详解
2019/08/30 Python
浅谈django channels 路由误导
2020/05/28 Python
Python3自带工具2to3.py 转换 Python2.x 代码到Python3的操作
2021/03/03 Python
HTML5中微数据概述及在搜索引擎中的使用举例
2013/02/07 HTML / CSS
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
怎样建立和理解非常复杂的声明?例如定义一个包含N 个指向返回 指向字符的指针的函数的指针的数组?
2013/03/19 面试题
建筑工程实习自我鉴定
2013/09/19 职场文书
初一地理教学反思
2014/01/16 职场文书
《翻越远方的大山》教学反思
2014/04/13 职场文书
医生见习报告范文
2014/11/03 职场文书
2014年反腐倡廉工作总结
2014/12/05 职场文书
大学生入党自我鉴定范文
2019/06/21 职场文书
php 原生分页
2021/04/01 PHP
Golang 如何实现函数的任意类型传参
2021/04/29 Golang
Springboot使用Spring Data JPA实现数据库操作
2021/06/30 Java/Android
python中的sys模块和os模块
2022/03/20 Python