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 相关文章推荐
初探PHP5
Oct 09 PHP
用PHP和ACCESS写聊天室(二)
Oct 09 PHP
PHP-CGI进程CPU 100% 与 file_get_contents 函数的关系分析
Aug 15 PHP
PHP高自定义性安全验证码代码
Nov 27 PHP
关于PHP语言构造器介绍
Jul 08 PHP
php实现批量下载百度云盘文件例子分享
Apr 10 PHP
PHP文件上传判断file是否己选择上传文件的方法
Nov 10 PHP
php基础设计模式大全(注册树模式、工厂模式、单列模式)
Aug 31 PHP
PHP与jquery实时显示网站在线人数实例详解
Dec 02 PHP
thinkPHP5框架分页样式类完整示例
Sep 01 PHP
PHP常用函数之根据生日计算年龄功能示例
Oct 21 PHP
php查看一个变量的占用内存的实例代码
Mar 29 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 缓存实现代码及详细注释
2010/05/16 PHP
Laravel 5框架学习之向视图传送数据
2015/04/08 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
2017/08/31 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
在chrome浏览器中,防止input[text]和textarea在聚焦时出现黄色边框的解决方法
2011/05/24 Javascript
JS中处理与当前时间间隔的函数代码
2012/05/23 Javascript
简单实用jquery版三级联动select示例
2013/07/04 Javascript
js获取某元素的class里面的css属性值代码
2014/01/16 Javascript
jquery 扑捉回车键事件代码
2014/04/24 Javascript
网页右下角弹出窗体实现代码
2014/06/05 Javascript
js创建对象的区别示例介绍
2014/07/24 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
js的touch事件的实际引用
2014/10/13 Javascript
解决node.js安装包失败的几种方法
2016/09/02 Javascript
easyui导出excel无法弹出下载框的快速解决方法
2016/11/10 Javascript
Vue.js 2.0 移动端拍照压缩图片预览及上传实例
2017/04/27 Javascript
vue2.0 子组件改变props值,并向父组件传值的方法
2018/03/01 Javascript
JS实现全屏预览F11功能的示例代码
2018/07/23 Javascript
layDate插件设置开始和结束时间
2018/11/15 Javascript
解决JS表单验证只有第一个IF起作用的问题
2018/12/04 Javascript
分享JS表单验证源码(带错误提示及密码等级)
2020/01/05 Javascript
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
python中的break、continue、exit()、pass全面解析
2017/08/05 Python
解决python 未发现数据源名称并且未指定默认驱动程序的问题
2018/12/07 Python
Python使用pyautocad+openpyxl处理cad文件示例
2019/07/11 Python
tensorflow与numpy的版本兼容性问题的解决
2021/01/08 Python
如何查看浏览器对html5的支持情况
2020/12/15 HTML / CSS
EQVVS官网:设计师男装和女装
2018/10/24 全球购物
How to spawning asynchronous work in J2EE
2016/08/29 面试题
搞笑创意广告语
2014/03/17 职场文书
捐款倡议书
2014/04/14 职场文书
婚礼新人答谢词
2015/01/04 职场文书
2015年宣传部个人工作总结
2015/05/14 职场文书
刑事案件上诉状
2015/05/23 职场文书
500字作文之难忘的同学
2019/12/20 职场文书