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 minixml详解
Jul 19 PHP
jQuery EasyUI API 中文文档 - DateBox日期框
Oct 15 PHP
深入PHP数据缓存的使用说明
May 10 PHP
PHP读取RSS(Feed)简单实例
Jun 12 PHP
PHP实现UTF-8文件BOM自动检测与移除实例
Nov 05 PHP
CI框架中通过hook的方式实现简单的权限控制
Jan 07 PHP
php文件下载处理方法分析
Apr 22 PHP
PHP人民币金额转大写实例代码
Oct 02 PHP
thinkphp跨库操作的简单代码实例
Sep 22 PHP
php 运算符与表达式详细介绍
Nov 30 PHP
PHP微信分享开发详解
Jan 14 PHP
浅谈PHP错误类型及屏蔽方法
May 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
ThinkPHP使用心得分享-上传类UploadFile的使用
2014/05/15 PHP
php获取ip及网址的简单方法(必看)
2017/04/01 PHP
浅谈laravel框架与thinkPHP框架的区别
2019/10/23 PHP
JQuery 学习笔记 选择器之六
2009/07/23 Javascript
Jquery easyUI 更新行示例
2014/03/06 Javascript
javascript匿名函数应用示例介绍
2014/03/07 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
2015/04/14 Javascript
浅谈javascript语法和定时函数
2015/05/03 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
B/S(Web)实时通讯解决方案分享
2017/04/06 Javascript
深入浅析Node环境和浏览器的区别
2018/08/14 Javascript
vue中引入mxGraph的步骤详解
2019/05/17 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
jstree中的checkbox默认选中和隐藏示例代码
2019/12/29 Javascript
原生js实现点击轮播切换图片
2020/02/11 Javascript
微信小程序 接入腾讯地图的两种写法
2021/01/12 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
JavaScript实现打字游戏
2021/02/19 Javascript
python实现跨文件全局变量的方法
2014/07/07 Python
简单介绍Python中利用生成器实现的并发编程
2015/05/04 Python
python结合shell查询google关键词排名的实现代码
2016/02/27 Python
python中利用xml.dom模块解析xml的方法教程
2017/05/24 Python
python实现顺序表的简单代码
2018/09/28 Python
Python一句代码实现找出所有水仙花数的方法
2018/11/13 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
Python 常用模块 re 使用方法详解
2019/06/06 Python
Django 实现外键去除自动添加的后缀‘_id’
2019/11/15 Python
基于Python实现简单学生管理系统
2020/07/24 Python
使用Python实现音频双通道分离
2020/12/25 Python
纯CSS3编写的的精美动画进度条(无flash/无图像/无脚本/附源码)
2013/01/07 HTML / CSS
编程输出如下图形
2013/11/24 面试题
土木工程个人自荐信范文
2013/11/30 职场文书
《火烧云》教学反思
2014/04/12 职场文书
法定代表人授权委托书范本
2014/10/07 职场文书
大学学生会主席竞选稿
2015/11/19 职场文书
对象析构函数__del__在Python中何时使用
2022/03/22 Python