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中定时计划任务的实现原理
Jan 08 PHP
浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)
Jun 29 PHP
PHP获取一个字符串中间一部分字符的方法
Aug 19 PHP
浅析PHP中strlen和mb_strlen的区别
Aug 31 PHP
php最简单的删除目录与文件实现方法
Nov 28 PHP
php+xml编程之SimpleXML的应用实例
Jan 24 PHP
yii添删改查实例
Nov 16 PHP
PHP几个实用自定义函数小结
Jan 25 PHP
php图形jpgraph操作实例分析
Feb 22 PHP
visual studio code 调试php方法(图文详解)
Sep 15 PHP
PHP实现断点续传乱序合并文件的方法
Sep 06 PHP
swoole锁的机制代码实例讲解
Mar 04 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 判断字符串是中文还是英文, 或者是中英混合
2021/03/09 PHP
JavaScript 利用Cookie记录用户登录信息
2009/12/08 Javascript
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
了解一点js的Eval函数
2012/07/26 Javascript
Jquery 选中表格一列并对表格排序实现原理
2012/12/15 Javascript
JavaScript 函数惰性载入的实现及其优点介绍
2013/08/12 Javascript
js面向对象编程之如何实现方法重载
2014/07/02 Javascript
JavaScript插件化开发教程(六)
2015/02/01 Javascript
javascript生成大小写字母
2015/07/03 Javascript
学习JavaScript设计模式(链式调用)
2015/11/26 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
2015/12/09 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
AngularJS中如何使用$parse或$eval在运行时对Scope变量赋值
2016/01/25 Javascript
基于jQuery实现select下拉选择可输入附源码下载
2016/02/03 Javascript
jquery if条件语句的写法
2016/05/19 Javascript
基于jQuery实现中英文切换导航条效果
2016/09/18 Javascript
js定时器实例分享
2016/12/20 Javascript
Angular2 组件通信的实例代码
2017/06/23 Javascript
浅谈redux, koa, express 中间件实现对比解析
2019/05/23 Javascript
Antd下拉选择,自动匹配功能的实现
2020/10/24 Javascript
[02:42]2014DOTA2国际邀请赛 三冰专访:我会打到Ti20
2014/07/13 DOTA
[02:32]“虐狗”镜头慎点 2016国际邀请赛中国区预选赛现场玩家采访
2016/06/28 DOTA
跟老齐学Python之从if开始语句的征程
2014/09/14 Python
Python多线程编程简单介绍
2015/04/13 Python
举例讲解Python设计模式编程的代理模式与抽象工厂模式
2016/01/16 Python
Python简单实现自动删除目录下空文件夹的方法
2017/08/29 Python
目前最全的python的就业方向
2018/06/05 Python
python单线程下实现多个socket并发过程详解
2019/07/27 Python
Python如何使用ConfigParser读取配置文件
2020/11/12 Python
python爬虫用scrapy获取影片的实例分析
2020/11/23 Python
介绍一下OSI七层模型
2012/07/03 面试题
入党申请书自我鉴定
2013/10/12 职场文书
2014年母亲节寄语
2014/05/07 职场文书
镇人大副主席民主生活会对照检查材料思想汇报
2014/10/01 职场文书
2015民办小学年度工作总结
2015/05/26 职场文书
2020年元旦祝福语录,总有适合你的
2019/12/31 职场文书