PHP - 如何有效地读取大型远程文件并在循环中使用缓冲区


PHP - how to read big remote files efficiently and use buffer in loop

我想了解如何使用读取文件的缓冲区。

假设我们有一个大文件,其中包含逐行的电子邮件列表(分隔符是经典'n

现在,我们希望将每一行与数据库中表的每条记录进行比较,例如 line_of_file == table_row .

如果您有普通文件,

这是一项简单的任务,否则,如果您有一个巨大的文件,服务器通常会在几分钟后停止操作。

那么使用文件缓冲区做这种事情的最佳方法是什么?

到目前为止,我所拥有的是这样的:

$buffer = file_get_contents('file.txt');
while($row = mysql_fetch_array($result)) {
  if ( preg_match('/'.$email.'/im',$buffer)) {
    echo $row_val;
  }
}

$buffer = file_get_contents('file.txt');
$lines = preg_split('/'n/',$buffer); 
//or $lines = explode(''n',$buffer);
while($row = mysql_fetch_array($result)) {
  if ( in_array($email,$lines)) {
    echo $row_val;
  }
}

就像我在对您的问题的关闭投票中已经建议的那样(因此 CW):

您可以使用实现迭代器的 SplFileObject 逐行迭代文件以节省内存。查看我的答案

  • 在 PHP 中读取文件的内存占用最少的方式和
  • 在 PHP 中读取文件时如何节省内存?

例如。

不要对大文件使用 file_get_contents。 这会一次将整个文件全部拉入内存中。 你必须零碎地阅读它

$fp = fopen('file.txt', 'r');
while(!feof($fp)){
  //get onle line 
  $buffer = fgets($fp);
   //do your stuff
}
 fclose($fp);

使用 fopen() 打开文件并增量读取。 可能一次一行,fgets().

file_get_contents将整个文件读入内存,如果文件大于几兆字节,则不希望这样做

根据这需要多长时间,您可能需要担心 PHP 执行时间限制,或者如果浏览器在 2 分钟内没有收到任何输出,则浏览器超时。

您可以尝试的操作:

  1. set_time_limit(0)避免遇到 PHP 时间限制
  2. 确保每
  3. 30秒左右输出一些数据,这样浏览器就不会超时;确保flush();并可能ob_flush();,以便您的输出实际上是通过网络发送的(这是一个笨拙)
  4. 启动一个单独的进程(例如通过exec())在后台运行。 老实说,任何超过一两秒的事情最好在后台运行