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 相关文章推荐
phpmyadmin 3.4 空密码登录的实现方法
May 29 PHP
php中inlcude()性能对比详解
Sep 16 PHP
php删除字符串末尾子字符,删除开始字符,删除两端字符(实现代码)
Jun 27 PHP
php mysql_real_escape_string函数用法与实例教程
Sep 30 PHP
PHP使用静态方法的几个注意事项
Sep 16 PHP
使用URL传输SESSION信息
Jul 14 PHP
Yii2使用swiftmailer发送邮件的方法
May 03 PHP
mysql desc(DESCRIBE)命令实例讲解
Sep 24 PHP
PHP查询分页的实现代码
Jun 09 PHP
php取出数组单个值的方法
Mar 12 PHP
laravel清除视图缓存的代码
Oct 23 PHP
PHP单元测试配置与使用方法详解
Dec 27 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数据流应用的一个简单实例
2012/09/14 PHP
php实现mysql数据库分表分段备份
2015/06/18 PHP
PHP下载大文件失败并限制下载速度的实例代码
2019/05/10 PHP
javascript for循环设法提高性能
2010/02/24 Javascript
使用javascript创建快捷方式的简单实例
2013/08/09 Javascript
js综合应用实例简单的表格统计
2013/09/03 Javascript
javascript校验价格合法性实例(必须输入2位小数)
2014/05/05 Javascript
Javascript基础教程之定义和调用函数
2015/01/18 Javascript
jQuery实现数秒后自动提交form的方法
2015/03/05 Javascript
JS实现鼠标滑过链接改变网页背景颜色的方法
2015/10/20 Javascript
js 声明数组和向数组中添加对象变量的简单实例
2016/07/28 Javascript
AngularJS中的JSONP实例解析
2016/12/01 Javascript
深入理解vue.js双向绑定的实现原理
2016/12/05 Javascript
JS验证字符串功能
2017/02/22 Javascript
如何使用bootstrap框架 bootstrap入门必看!
2017/04/13 Javascript
浅谈angular4生命周期钩子
2017/09/05 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
2018/12/05 Javascript
基于Proxy的小程序状态管理实现
2019/06/14 Javascript
node+multer实现图片上传的示例代码
2020/02/18 Javascript
Python中有趣在__call__函数
2015/06/21 Python
python解决pandas处理缺失值为空字符串的问题
2018/04/08 Python
详解numpy的argmax的具体使用
2019/05/27 Python
Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统
2019/09/05 Python
spyder 在控制台(console)执行python文件,debug python程序方式
2020/04/20 Python
python函数调用,循环,列表复制实例
2020/05/03 Python
Python调用OpenCV实现图像平滑代码实例
2020/06/19 Python
在Tensorflow中实现leakyRelu操作详解(高效)
2020/06/30 Python
python 浮点数四舍五入需要注意的地方
2020/08/18 Python
Python 实现集合Set的示例
2020/12/21 Python
CSS3 mask 遮罩的具体使用方法
2017/11/03 HTML / CSS
Ever New加拿大官网:彰显女性美
2018/10/05 全球购物
公务员转正鉴定材料
2014/02/11 职场文书
小区消防演习方案
2014/02/21 职场文书
2015年超市收银员工作总结
2015/04/25 职场文书
2015教师个人德育工作总结
2015/07/22 职场文书
浅谈Redis位图(Bitmap)及Redis二进制中的问题
2021/07/15 Redis