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

时间:2011-05-11 21:07:09

标签: php file buffer

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

假设我们有一个大文件,其中包含逐行电子邮件列表(分隔符是经典的\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;
  }
}

3 个答案:

答案 0 :(得分:3)

就像我在你的问题的密切投票中所提出的那样(因此CW):

您可以使用实现Iterator的SplFileObject逐行迭代文件以节省内存。请参阅我对

的回答

例如。

答案 1 :(得分:2)

不要将file_get_contents用于大文件。这会将整个文件同时拉入内存。你必须把它读成片

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

答案 2 :(得分:1)

使用fopen()打开文件并逐步读取。可能一次只有一行fgets()

file_get_contents将整个文件读入内存,如果文件大于几兆字节,这是不可取的

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

你可能尝试的事情:

  1. set_time_limit(0)以避免错过PHP时间限制
  2. 确保每30秒左右输出一些数据,以便浏览器不会超时;请确保flush();和可能ob_flush();,以便您的输出实际通过网络发送(这是一个kludge)
  3. 启动一个单独的过程(例如通过exec())以在后台运行此过程。老实说,任何需要超过一两秒的东西最好在后台运行