代码之家  ›  专栏  ›  技术社区  ›  jacobangel

使用PHP解析大型文本文件,而不杀死服务器

  •  1
  • jacobangel  · 技术社区  · 17 年前

    我正在尝试读取一些大型文本文件(介于50米到200米之间),执行简单的文本替换(基本上,在一些常规情况下,我没有正确地转义XML)。以下是函数的简化版本:

    <?php
    function cleanFile($file1, $file2) {
    $input_file     = fopen($file1, "r");
    $output_file    = fopen($file2, "w");
      while (!feof($input_file)) {
        $buffer = trim(fgets($input_file, 4096));
        if (substr($buffer,0, 6) == '<text>' AND substr($buffer,0, 15) != '<text><![CDATA[')
        {
          $buffer = str_replace('<text>', '<text><![CDATA[', $buffer);
          $buffer = str_replace('</text>', ']]></text>', $buffer);
        }
       fputs($output_file, $buffer . "\n");
      }
      fclose($input_file);
      fclose($output_file);     
    }
    ?>
    

    我没有得到的是,对于最大的文件,大约150MB,在失败之前,php内存使用量会偏离图表(大约2GB)。我认为这是阅读大文件最有效的方法。有没有什么方法可以提高记忆的效率?也许是一些在应该收集东西的时候将其保存在内存中的设置?

    换句话说,它不起作用,我不知道为什么,据我所知,我没有做错事。我该怎么走?谢谢你的意见。

    3 回复  |  直到 17 年前
        1
  •  3
  •   Randolpho    17 年前

    PHP并不是专门为这个设计的。将工作卸载到另一个进程并调用它或从PHP启动它。我建议使用 Python Perl .

        2
  •  1
  •   freespace    17 年前

    从我对PHP的垃圾收集的理解来看,以下内容可能会有所帮助:

    1. unset $buffer 当您将它写到磁盘上之后,显式地告诉GC清理它。
    2. if 在另一个函数中阻塞,因此当该函数退出时,GC将运行。

    这些建议背后的原因是,我怀疑垃圾收集器没有释放内存,因为所有操作都是在一个函数内完成的,而GC是垃圾。

        3
  •  0
  •   user1342582    17 年前

    我希望这在很多情况下都会失败。您正在读取4096字节的块。谁知道截止线不会在 <text> ?在这种情况下,你的 str_replace 不起作用。

    你考虑过使用正则表达式吗?