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控制网页过期时间的代码
Sep 28 PHP
PHP初学者最感迷茫的问题小结
Mar 27 PHP
PHP开发的一些注意点总结
Oct 12 PHP
php学习之运算符相关概念
Jun 09 PHP
linux下使用ThinkPHP需要注意大小写导致的问题
Aug 02 PHP
php-fpm配置详解
Feb 12 PHP
php中字符集转换iconv函数使用总结
Oct 11 PHP
在WordPress中获取数据库字段内容和添加主题设置菜单
Jan 11 PHP
PHP实现将多个文件压缩成zip格式并下载到本地的方法示例
May 23 PHP
Laravel Validator 实现两个或多个字段联合索引唯一
May 08 PHP
laravel利用中间件做防非法登录和权限控制示例
Oct 21 PHP
ThinkPHP5分页paginate代码实例解析
Nov 10 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数据结构之顺序链表与链式线性表示例
2018/01/22 PHP
Laravel 创建指定表 migrate的例子
2019/10/09 PHP
javascript 建设银行登陆键盘
2008/06/10 Javascript
通过javascript的匿名函数来分析几段简单有趣的代码
2010/06/29 Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
2012/01/15 Javascript
location对象的属性和方法应用(解析URL)
2013/04/12 Javascript
Jquery ajax执行顺序 返回自定义错误信息(实例讲解)
2013/11/06 Javascript
JS+CSS 制作的超级简单的下拉菜单附图
2013/11/22 Javascript
用jQuery与JSONP轻松解决跨域访问的问题
2014/02/04 Javascript
JavaScript 实现简单的倒计时弹窗DEMO附图
2014/03/05 Javascript
JS实现可点击展开与关闭的左侧广告代码
2015/09/02 Javascript
老生常谈遮罩层 滚动条的问题
2016/04/29 Javascript
JS判断日期格式是否合法的简单实例
2016/07/11 Javascript
jQuery绑定事件的四种方式介绍
2016/10/31 Javascript
预防网页挂马的方法总结
2016/11/03 Javascript
使用JQ完成表格隔行换色的简单实例
2017/08/25 Javascript
基于滚动条位置判断的简单实例
2017/12/14 Javascript
vue实现动态按钮功能
2019/05/13 Javascript
js实现图片粘贴到网页
2019/12/06 Javascript
详解vue beforeEach 死循环问题解决方法
2020/02/25 Javascript
[03:46]显微镜下的DOTA2第七期——满血与残血
2014/06/20 DOTA
Python装饰器的函数式编程详解
2015/02/27 Python
Python正则抓取网易新闻的方法示例
2017/04/21 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
Python实现的微信好友数据分析功能示例
2018/06/21 Python
Python使用Flask-SQLAlchemy连接数据库操作示例
2018/08/31 Python
Python多进程方式抓取基金网站内容的方法分析
2019/06/03 Python
Python 的 __str__ 和 __repr__ 方法对比
2020/09/02 Python
Cpython解释器中的GIL全局解释器锁
2020/11/09 Python
潘多拉珠宝英国官方网上商店:PANDORA英国
2018/06/12 全球购物
平面设计的岗位职责
2013/11/08 职场文书
励志广播稿300字(5篇)
2014/09/15 职场文书
领导班子整改方案
2014/10/25 职场文书
离婚被告答辩状
2015/05/22 职场文书
Python机器学习应用之工业蒸汽数据分析篇详解
2022/01/18 Python
HTML5基础学习之文本标签控制
2022/03/25 HTML / CSS