zoukankan      html  css  js  c++  java
  • PHP读取大文件的几种方法

    场景:PHP读取超大文件,例如1G的日志文件,我这里使用的是400M的access.log文件

    1、使用file直接读取

    <?php
    $starttime=microtime_float();
    
    ini_set('memory_limit', '-1');
    $file = 'testfile.txt';
    
    $data = file($file);
    $line = $data[count($data) - 1000];
    $endtime=microtime_float();
    
    echo count($data),"<br/>";
    echo $endtime-$starttime;
    
    function microtime_float(){
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    } 
    ?>
    

    运行结果:10127784 行   共使用了,7.8764359951s
    我的电脑是3G内存,此方法不是推荐使用,因为需要把文件全部载入内存

    2、使用linux命令  tail

    <?php
    
    $starttime=microtime_float();
    
    $file = 'testfile.txt';
    $file = escapeshellarg($file); // 对命令行参数进行安全转义
    $line = `tail -n 100 $file`;
    
    echo $line,"<br/>";
    
    $endtime=microtime_float();
    echo $endtime-$starttime;
    
    function microtime_float(){
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    } 
    
    //end 
    

    运行结果:只使用了几毫秒轻松搞定这种方法不能在windows下使用

    3、使用fseek函数


    这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,因为PHP是C写的,所以实现的时候也类似C读取文件,通过指针的移动,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的几种方法
    方法一:使用fopen打开文件(从文件指针资源句柄)

    <?php
    $starttime=microtime_float();
    
    $file = 'testfile.txt';
    $fp = fopen($file, "r+");
    
    $line = 100;
    $pos = -2;
    $t =$data="";
    
    while ($line > 0)
    {
     while ($t != "
    ") //换行符
     {
      fseek($fp, $pos, SEEK_END);//移动指针
      $t = fgetc($fp);//获取一个字符
      $pos--;//向前偏移
     }
    
     $t = "";
     $data = fgets($fp);//获取当前行的数据
     $line--;
    }
    fclose($fp);
    echo $data,"<br/>";
    $endtime=microtime_float();
    
    echo $endtime-$starttime;
    
    function microtime_float(){
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    } 
    ?>
    

    运行结果:0.338493108749

    方法二:一块一块的读取

    <?php
    $starttime=microtime_float();
    
    $file = 'testfile.txt';
    $fp = fopen($file, "r");
    $num = 10;
    $chunk = 4096;//4K的块
    $fs = sprintf("%u", filesize($file));
    $readData='';
    $max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : $fs;
    
    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, "
    ") >= $num + 1) {
    
        $ns=substr_count($readData, "
    ")-$num+2;
        preg_match('/(.*?
    ){'.$ns.'}/',$readData,$match);
        $data = $match[1];
        break;
    }
    }
    fclose($fp);
    echo $data,"<br/>";
    
    
    $endtime=microtime_float();
    
    echo $endtime-$starttime;
    
    function microtime_float(){
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    } 
    ?>
    

     

    运行时间:0.00199198722839

  • 相关阅读:
    MySQL server version for the right syntax to use near ‘USING BTREE
    随笔
    [python]自问自答:python -m参数?
    [linux]查看linux下端口占用
    [linux]scp指令
    [编程题目]泥塑课
    How can I learn to program?
    [python]在场景中理解装饰器
    [前端]分享一个Bootstrap可视化布局的网站
    [python]python元类
  • 原文地址:https://www.cnblogs.com/chenpingzhao/p/4547165.html
Copyright © 2011-2022 走看看