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 相关文章推荐
第一节--面向对象编程
Nov 16 PHP
php 文件状态缓存带来的问题
Dec 14 PHP
PHP中常用的输出函数总结
Sep 22 PHP
php防止网站被刷新的方法汇总
Dec 01 PHP
ThinkPHP、ZF2、Yaf、Laravel框架路由大比拼
Mar 25 PHP
关于php微信订阅号开发之token验证后自动发送消息给订阅号但是没有消息返回的问题
Dec 21 PHP
YII2自动登录Cookie总是失效的解决方法
Jun 28 PHP
PHP whois查询类定义与用法示例
Apr 03 PHP
Laravel手动返回错误码示例
Oct 22 PHP
Laravel等框架模型关联的可用性浅析
Dec 15 PHP
PHP查找一列有序数组是否包含某值的方法
Feb 07 PHP
关于Anemometer图形化显示MySQL慢日志的工具搭建及使用的详细介绍
Jul 13 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 imagecreatefrombmp 从BMP文件或URL新建一图像
2012/07/16 PHP
PHP图片处理之图片背景、画布操作
2014/11/19 PHP
php中使用gd库实现远程图片下载实例
2015/05/12 PHP
PHP-FPM 的管理和配置详解
2019/02/17 PHP
php输出反斜杠的实例方法
2019/09/19 PHP
JQuery异步获取返回值中文乱码的解决方法
2015/01/29 Javascript
js文本框走动跑马灯效果代码分享
2015/08/25 Javascript
jQuery+CSS3实现3D立方体旋转效果
2015/11/10 Javascript
javascript作用域链(Scope Chain)用法实例解析
2015/11/30 Javascript
Javascript 函数的四种调用模式
2016/11/05 Javascript
解析jQueryEasyUI的使用
2016/11/22 Javascript
Angular的MVC和作用域
2016/12/26 Javascript
详解JavaScript常量定义
2017/01/03 Javascript
bootstrap-table组合表头的实现方法
2017/09/07 Javascript
vue2导航根据路由传值,而改变导航内容的实例
2017/11/10 Javascript
浅谈微信小程序之官方UI框架we-ui使用教程
2018/08/20 Javascript
解决Idea、WebStorm下使用Vue cli脚手架项目无法使用Webpack别名的问题
2019/10/11 Javascript
JS数组扁平化、去重、排序操作实例详解
2020/02/24 Javascript
jQuery+css实现的点击图片放大缩小预览功能示例【图片预览 查看大图】
2020/05/29 jQuery
UEditor 自定义图片视频尺寸校验功能的实现代码
2020/10/20 Javascript
vue如何使用rem适配
2021/02/06 Vue.js
详解python配置虚拟环境
2019/04/08 Python
python3通过selenium爬虫获取到dj商品的实例代码
2019/04/25 Python
bluepy 一款python封装的BLE利器简单介绍
2019/06/25 Python
python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法
2019/10/04 Python
查看keras的默认backend实现方式
2020/06/19 Python
python绘制分布折线图的示例
2020/09/24 Python
经典c++面试题二
2015/08/14 面试题
创联软件面试题笔试题
2012/10/07 面试题
营销人才自我鉴定范文
2013/12/25 职场文书
校庆活动策划方案
2014/06/05 职场文书
领导班子遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
2014年志愿者工作总结
2014/11/20 职场文书
六年级数学教学反思
2016/02/16 职场文书
关于Nginx中虚拟主机的一些冷门知识小结
2022/03/03 Servers
SONY AN-LP1 短波有源天线放大器图
2022/04/05 无线电