使用PHP解析大型文本文件而不关闭服务器

使用PHP解析大型文本文件而不关闭服务器,php,memory,parsing,Php,Memory,Parsing,我正在尝试读取一些大的文本文件(介于5000万到200万之间),进行简单的文本替换(基本上,在一些常规情况下,我没有正确地转义xml)。以下是该函数的简化版本: <?php function cleanFile($file1, $file2) { $input_file = fopen($file1, "r"); $output_file = fopen($file2, "w"); while (!feof($input_file)) { $buffer = tr

我正在尝试读取一些大的文本文件(介于5000万到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)。我认为这是读取大文件最有效的内存方式。有没有我缺少的更有效的记忆方法?也许是某个设置在应该收集的时候将东西保存在内存中


换句话说,它不起作用,我也不知道为什么,就我所知,我并没有做错事。我要去哪里?谢谢你的意见

PHP并不是专门为此而设计的。将工作转移到另一个进程,并调用它或从PHP启动它。我建议使用or。

PHP并不是专门为此设计的。将工作转移到另一个进程,并调用它或从PHP启动它。我建议使用or。

根据我对PHP垃圾收集的有限了解,以下内容可能会有所帮助:

  • unset
    $buffer
    将其写入磁盘后,显式地告诉GC清理它
  • if
    块放在另一个函数中,以便在该函数退出时运行GC

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

    根据我对PHP垃圾收集的微薄理解,以下内容可能会有所帮助:

  • unset
    $buffer
    将其写入磁盘后,显式地告诉GC清理它
  • if
    块放在另一个函数中,以便在该函数退出时运行GC

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

    我预计在许多情况下都会失败。您正在读取4096字节的数据块。谁知道截止时间不会在<代码> <代码>的中间?在这种情况下,
    str\u replace
    将不起作用


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

    我认为在很多情况下,这会失败。您正在读取4096字节的数据块。谁知道截止时间不会在<代码> <代码>的中间?在这种情况下,
    str\u replace
    将不起作用


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

    不幸的是,目前还不能选择其他语言:(然后在单独的进程中使用PHP进行解析。重点是,您不应该在请求中解析那个大文件。您应该在单独的进程中卸载工作,返回响应,然后允许第二个请求来确定进程id是否完成。Asynchronous FTW.Agreed。我猜您正在接收文件viftp、批处理等。为什么不在文件到达文件系统后立即解析文件,而不是等待有人从web请求中将其下拉。嘿……刚刚注意到输入错误…我的意思是“进程完成”而不是“进程id完成”。:Dun幸运的是,在这一点上,选择另一种语言是不可取的(然后在单独的进程中使用PHP进行解析。重点是,您不应该在请求中解析那个大文件。您应该在单独的进程中卸载工作,返回响应,然后允许第二个请求来确定进程id是否完成。Asynchronous FTW.Agreed。我猜您正在接收文件viftp、批处理等。为什么不在文件到达文件系统后立即解析文件,而不是等待有人从web请求中将其删除。嘿……刚刚注意到输入错误……我的意思是“进程已完成”而不是“进程id已完成”:D试过这个。它确实释放了一点内存,但还不够。我希望我知道它在内存中到底做了什么。试过这个。它确实释放了一点内存,但还不够。我希望我知道它在内存中到底做了什么。看