【问题标题】:php read large text file logphp读取大文本文件日志
【发布时间】:2011-01-27 21:37:04
【问题描述】:

我有一个文本日志文件,大约 600 MB。

我想使用 php 读取它并在 html 页面上显示数据,但我只需要每次运行脚本时添加的最后 18 行。

由于它是一个大文件,我无法将其全部读取,然后像我希望的那样翻转数组。他们是另一种方式吗?

【问题讨论】:

  • 可以执行外部命令吗?调用 Linux/Unix 的 tailexec() 可能是最简单的方法。
  • 我有 root 权限,但理想情况下我也想向我的用户推广它……使用 unix 方式会不会是一个安全问题?

标签: php


【解决方案1】:

使用fopenfilesizefseek 打开文件并仅在接近文件末尾时开始读取。

fseek 手册页上的评论包括读取大文件最后 X 行的完整代码。

【讨论】:

    【解决方案2】:

    将该大小的文件加载到内存中可能不是一个好主意。这应该可以解决这个问题。

    $file = escapeshellarg($file);
    $line = 'tail -n 18 '.$file;
    system($line);
    

    【讨论】:

    • 我需要什么权限才能做到这一点?
    • 正常权限就足够了。也许你需要 chown 文件。
    【解决方案3】:

    您可以使用向后流式传输它

    $file = popen("tac $filename",'r');
    
    while ($line = fgets($file)) {
      echo $line;
    }
    

    【讨论】:

      【解决方案4】:

      最好的方法是使用 fread 和 fgets 逐行读取,这非常快,因为一次只读取一行而不是 while 文件:

      使用示例如下:

      $handle = fopen("/logs/log.txt", "r")
      if ($handle)
      {
          fseek($handle,-18,SEEK_END); //Seek to the end minus 18 lines
          while (!feof($handle))
          {
              echo fgets($handle, 4096); //Make sure your line is less that 4096, otherwise update
              $line++;
          }
          fclose($handle);
      }
      

      【讨论】:

      • 是的,我看错了他最后说的那一行,我以为他想要前 18 个。
      • 这是高内存消耗 ... 134217728 字节的允许内存大小已用完
      【解决方案5】:

      为了记录,遇到同样的问题并在这里尝试了所有解决方案。

      事实证明,Dagon 的 popen "tac $filename" 方式是最快的,也是内存和 CPU 负载最低的方式。

      使用 2Gb 日志文件进行测试,每次读取 500、1000 和 2000 行。光滑的。谢谢。

      【讨论】:

        猜你喜欢
        • 2011-03-30
        • 2015-06-04
        • 1970-01-01
        • 2018-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多