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 相关文章推荐
不用GD库生成当前时间的PNG格式图象的程序
Oct 09 PHP
php连接mysql数据库代码
Mar 10 PHP
php echo 输出字符串函数详解
May 13 PHP
php数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
Oct 31 PHP
表格展示无限级分类(PHP版)
Aug 21 PHP
PHP 线程安全与非线程安全版本的区别深入解析
Aug 06 PHP
thinkphp的c方法使用示例
Feb 24 PHP
PHP获取浏览器信息类和客户端地理位置的2个方法
Apr 24 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
Jan 07 PHP
PHP错误处理函数
Apr 03 PHP
thinkPHP5使用Rabc实现权限管理
Aug 28 PHP
php实现图片压缩处理
Sep 09 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
让Json更懂中文(JSON_UNESCAPED_UNICODE)
2011/10/27 PHP
php mysql实现mysql_select_db选择数据库
2016/12/30 PHP
List Information About the Binary Files Used by an Application
2007/06/11 Javascript
js 赋值包含单引号双引号问题的解决方法
2014/02/26 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
深入理解JavaScript系列(30):设计模式之外观模式详解
2015/03/03 Javascript
jquery验证邮箱格式是否正确实例讲解
2015/11/16 Javascript
JS基于设计模式中的单例模式(Singleton)实现封装对数据增删改查功能
2018/02/06 Javascript
vue实现引入本地json的方法分析
2018/07/12 Javascript
详解如何使用koa实现socket.io官网的例子
2018/11/04 Javascript
React 实现拖拽功能的示例代码
2019/01/06 Javascript
浅谈redux, koa, express 中间件实现对比解析
2019/05/23 Javascript
Element实现表格分页数据选择+全选所有完善批量操作
2019/06/07 Javascript
[51:52]Liquid vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.24
2019/09/10 DOTA
[52:37]完美世界DOTA2联赛循环赛 Forest vs DM BO2第一场 10.29
2020/10/29 DOTA
python 不关闭控制台的实现方法
2011/10/23 Python
Python模块搜索概念介绍及模块安装方法介绍
2015/06/03 Python
python判断字符串是否是json格式方法分享
2017/11/07 Python
python使用Pycharm创建一个Django项目
2018/03/05 Python
Python3爬虫学习之应对网站反爬虫机制的方法分析
2018/12/12 Python
Python+OpenCV图像处理——实现轮廓发现
2020/10/23 Python
python os.listdir()乱码解决方案
2021/01/31 Python
CSS3过渡transition效果实例介绍
2016/05/03 HTML / CSS
美国大城市最热门旅游景点门票:CityPASS
2016/12/16 全球购物
瑞典时尚服装购物网站:Miinto.se
2017/10/30 全球购物
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
解释DataSet(ds) 和 ds as DataSet 的含义
2014/07/27 面试题
什么是TCP/IP
2014/07/27 面试题
网络工程系信息安全技术专业大学生求职信
2013/10/22 职场文书
理工学院学生自我鉴定
2014/02/23 职场文书
债务纠纷委托书范本
2014/10/14 职场文书
学生检讨书如何写
2014/10/30 职场文书
开票证明
2015/06/23 职场文书
中学政教处工作总结
2015/08/13 职场文书
商业计划书如何写?关键问题有哪些?
2019/07/11 职场文书
高效笔记技巧分享:学会这些让你不再困扰
2019/09/04 职场文书