加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

PHP读取大文件的几种方法介绍

发布时间:2016-11-27 07:16:16 所属栏目:大数据 来源:站长网
导读:读取大文件一直是一个头痛的问题,我们像使用php开发读取小文件可以直接使用各种函数实现,但一到大文章就会发现常用的方法是无法正常使用或时间太长太卡了,下面我们就一起来看看关于php读取大文件问题解决办法,希望例子能帮助到各位。 场景:PHP读取超

读取大文件一直是一个头痛的问题,我们像使用php开发读取小文件可以直接使用各种函数实现,但一到大文章就会发现常用的方法是无法正常使用或时间太长太卡了,下面我们就一起来看看关于php读取大文件问题解决办法,希望例子能帮助到各位。

场景:PHP读取超大文件,例如1G的日志文件,我这里使用的是400M的access.log文件

1、使用file直接读取

lt;#63;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),"lt;br/gt;";
echo $endtime-$starttime;
 
function microtime_float(){
  list($usec, $sec) = explode(" ", microtime());
  return ((float)$usec + (float)$sec);
}
#63;gt;

运行结果:10127784 行nbsp;nbsp; 共使用了,7.8764359951s

我的电脑是3G内存,此方法不是推荐使用,因为需要把文件全部载入内存

2、使用linux命令nbsp; tail

lt;#63;php
 
$starttime=microtime_float();
 
$file = 'testfile.txt';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 100 $file`;
 
echo $line,"lt;br/gt;";
 
$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打开文件(从文件指针资源句柄)

lt;#63;php
$starttime=microtime_float();
 
$file = 'testfile.txt';
$fp = fopen($file, "r+");
 
$line = 100;
$pos = -2;
$t =$data="";
 
while ($line gt; 0)
{
 while ($t != "n") //换行符
 {
 fseek($fp, $pos, SEEK_END);//移动指针
 $t = fgetc($fp);//获取一个字符
 $pos--;//向前偏移
 }
 
 $t = "";
 $data = fgets($fp);//获取当前行的数据
 $line--;
}
fclose($fp);
echo $data,"lt;br/gt;";
$endtime=microtime_float();
 
echo $endtime-$starttime;
 
function microtime_float(){
  list($usec, $sec) = explode(" ", microtime());
  return ((float)$usec + (float)$sec);
}
#63;gt;

运行结果:0.338493108749

方法二:一块一块的读取

lt;#63;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) #63; PHP_INT_MAX : $fs;
 
for($len = 0; $len lt; $max; $len += $chunk){
 
 $seekSize = ($max - $len gt; $chunk) #63; $chunk : $max - $len;
 fseek($fp, ($len + $seekSize) * -1, SEEK_END);
 $readData = fread($fp, $seekSize) . $readData;
 
if (substr_count($readData, "n") gt;= $num + 1) {
 
  $ns=substr_count($readData, "n")-$num+2;
  preg_match('/(.*#63;n){'.$ns.'}/',$readData,$match);
  $data = $match[1];
  break;
}
}
fclose($fp);
echo $data,"lt;br/gt;";
 
 
$endtime=microtime_float();
 
echo $endtime-$starttime;
 
function microtime_float(){
  list($usec, $sec) = explode(" ", microtime());
  return ((float)$usec + (float)$sec);
}
#63;gt;

运行时间:0.00199198722839

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读