PHP实现读取一个1G的文件大小


Posted in PHP onAugust 24, 2013

需求如下: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容。

1. 直接采用file函数来操作 or file_get_content() 肯定报内存溢出
注: 由于 file函数是一次性将所有内容读入内存,而php为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下 限制只能最大使用内存16M,这是通过php.ini里的memory_limit = 16M来进行设置,这个值如果设置-1,则内存使用量不受限制.

下面是一段用file来取出这具文件最后一行的代码.

ini_set('memory_limit','-1');
$file = 'access.log';
$data = file($file);
$line = $data[count($data)-1];2.直接调用linux的tail命令来显示最后几行

在linux命令行下,可以直接使用tail -n 10 access.log很轻易的显示日志文件最后几行,可以直接用php来调用tail命令,执行php代码如下.
file = 'access.log';
$file = escapeshellarg($file); // 对命令行参数进行安全转义
$line = `tail -n 1 $file`;
echo $line;3. 直接使用php的fseek来进行文件操作

这种方式是最为普遍的方式,它不需要将文件的内容全部读入内存,而是直接通过指针来操作,所以效率是相当高效的.在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法.

方法一:
首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置,再取这一行的位置,依次类推,直到找到了$num行。

function tail($fp,$n,$base=5)
{
    assert($n>0);
    $pos = $n+1;
    $lines = array();
    while(count($lines)< =$n){
        try{
            fseek($fp,-$pos,SEEK_END);
        } catch (Exception $e){
            fseek(0);
            break;
        }
        $pos *= $base;
        while(!feof($fp)){
            array_unshift($lines,fgets($fp));
        }
    }
    return array_slice($lines,0,$n);
}
var_dump(tail(fopen("access.log","r+"),10));

方法二 :
还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换行符(\n)的个数来判断是否已经读完最后$num行数据.

实现代码如下

$fp = fopen($file, "r");
$line = 10;
$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方法三:
$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file);
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) {
        preg_match("!(.*?\n){".($num)."}$!", $readData, $match);
        $data = $match[0];
        break;
    }
}
fclose($fp);
echo $data;
PHP 相关文章推荐
使用php shell命令合并图片的代码
Jun 23 PHP
屏蔽机器人从你的网站搜取email地址的php代码
Nov 14 PHP
setcookie中Cannot modify header information-headers already sent by错误的解决方法详解
May 08 PHP
php使用json_encode对变量json编码
Apr 07 PHP
初识Laravel
Oct 30 PHP
浅谈PHP解析URL函数parse_url和parse_str
Nov 11 PHP
PHP借助phpmailer发送邮件
May 11 PHP
php操作MongoDB类实例
Jun 17 PHP
Linux环境下php实现给网站截图的方法
May 03 PHP
windows环境下使用Composer安装ThinkPHP5
May 18 PHP
php框架CodeIgniter主从数据库配置方法分析
May 25 PHP
php的对象传值与引用传值代码实例讲解
Feb 26 PHP
一致性哈希算法以及其PHP实现详细解析
Aug 24 #PHP
PHP如何利用P3P实现跨域
Aug 24 #PHP
PHP引用符&amp;的用法详细解析
Aug 22 #PHP
新手菜鸟必读:session与cookie的区别
Aug 22 #PHP
PHP mysql与mysqli事务使用说明 分享
Aug 17 #PHP
php中url传递中文字符,特殊危险字符的解决方法
Aug 17 #PHP
测试PHP连接MYSQL成功与否的代码
Aug 16 #PHP
You might like
php文件怎么打开 如何执行php文件
2011/12/21 PHP
使用PHP编写的SVN类
2013/07/18 PHP
PHP中常见的缓存技术实例分析
2015/09/23 PHP
JavaScript中Math对象使用说明
2008/01/16 Javascript
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
node.js中的path.dirname方法使用说明
2014/12/09 Javascript
DOM 事件的深入浅出(一)
2016/12/05 Javascript
angular+ionic 的app上拉加载更新数据实现方法
2017/01/16 Javascript
vue2.0项目中使用Ueditor富文本编辑器示例代码
2017/08/14 Javascript
vue组件父子间通信详解(三)
2017/11/07 Javascript
jQuery实现checkbox即点即改批量删除及中间遇到的坑
2017/11/11 jQuery
在vue中,v-for的索引index在html中的使用方法
2018/03/06 Javascript
微信小程序如何获取手机验证码
2018/11/04 Javascript
Node.js安装详细步骤教程(Windows版)详解
2019/09/01 Javascript
Node如何后台数据库使用增删改查功能
2019/11/21 Javascript
javascript History对象原理解析
2020/02/17 Javascript
深度解读vue-resize的具体用法
2020/07/08 Javascript
js+for循环实现字符串自动转义的代码(把后面的字符替换前面的字符)
2020/12/24 Javascript
python使用matplotlib绘制折线图教程
2017/02/08 Python
Python3实现抓取javascript动态生成的html网页功能示例
2017/08/22 Python
Python3.6基于正则实现的计算器示例【无优化简单注释版】
2018/06/14 Python
Pytorch转onnx、torchscript方式
2020/05/25 Python
如何验证python安装成功
2020/07/06 Python
利用keras使用神经网络预测销量操作
2020/07/07 Python
Pycharm自带Git实现版本管理的方法步骤
2020/09/18 Python
python两个list[]相加的实现方法
2020/09/23 Python
美国高街时尚品牌:OASAP
2016/07/24 全球购物
John Varvatos官方网站:设计师男士时装
2017/02/08 全球购物
马来西亚和新加坡巴士票在线预订:CatchThatBus
2018/11/17 全球购物
运动鞋、街头服装、手表和手袋的实时市场:StockX
2020/11/25 全球购物
运动会闭幕式解说词
2014/02/21 职场文书
技校毕业生自荐信
2014/06/03 职场文书
2014年节能降耗工作总结
2014/12/11 职场文书
门店店长岗位职责
2015/04/14 职场文书
新娘婚礼致辞
2015/07/27 职场文书
MySQL 如何分析查询性能
2021/05/12 MySQL