PHP解压大文件

3

我正在尝试使用php zip归档解压缩一个巨大的文件(压缩后400多兆,解压后超过4G)。我只需要解压缩压缩文件中的一个csv文件。我感兴趣的文件解压后超过4G。我可以解压缩到文件末尾的前三个记录,但是进程会陷入无法结束的状态。这个进程没有输出、没有错误、没有循环,它只是一直运行下去。我不知道它在做什么。我的代码很简单:

$zip = new ZipArchive;
$res = $zip->open($file);
if ($res === TRUE) 
{
   $num = $zip->numFiles;
   for($i = 0; $i < $zip->numFiles; $i++) 
   {
      $filename = $zip->getNameIndex($i);
  // if its the file I want then...
      $content = '';
  // my output file  .. yes I've already checked to make sure the dir exists
      $unzipped = fopen($dir ."/2" . $filename  , 'wb');         
      $fp = $zip->getStream($filename);
      if(!$fp) exit("failed\n");
      while (!feof($fp))
      {
    $chunkSize = 10240;
    $contents = fread($fp, $chunkSize);
        $fwrite = fwrite($unzipped, $contents);
      }
      fclose($fp);
      fclose($unzipped);
    }

    $zip->close();
    fclose($filename);

}  

我删除了写入另一个文件以跟踪进度的语句,大多数文件都已经输出(如我所说,仅比整个文件少3条记录)...但是进程似乎走失了..它发生在fread上,我无法弄清楚正在发生什么..它还没有达到eof..源代码完好无损(在fread之前使用is_source($fp)进行检查),不会产生任何错误..关闭浏览器也无法停止它..甚至不能停止apache..必须关闭才能结束它...
有什么想法吗?谢谢。
3个回答

1
这只是一个猜测,但是尝试增加脚本可以分配的内存量。当我使用gzip函数时,我遇到了类似的问题,不得不进行此更改。
ini_set('memory_limit', '512M');

嗨,尼克,谢谢你的建议,我试过了,但没有任何改变...不过还是谢谢。 - Bridget

1

说实话,这听起来像是一个 PHP 的 bug。

你可以尝试输出对 memory_get_usage() 的调用来帮助你进行调试。但是,同时也要看看 stream_copy_to_stream(),因为你可以摆脱所有那些循环的垃圾。另外,保持一个写入字节的运行总数也可能很有趣,以查看问题出现的位置是否可疑。


根据文档页面上的某个人所说,该函数似乎会独自占用相当多的内存。因此,如果这是真的,并且内存是问题所在,那么这可能不是解决方案。 - Blizz
嗨,Chris,我尝试了一下,结果很有趣,它没有复制整个文件,但也没有出现错误,这让我相信第一个问题可能是初始的压缩流。它可能没有获取到所有内容,但这是另一个问题,在发布之前我需要进行一些研究。再次感谢。 - Bridget

0
$filename = '/media/file.gz';

$unzipped_content = '';   
$zd = gzopen($filename, "r");
while ($zip_file = gzread($zd, 10000000)){
    $unzipped_content.= $zip_file;
}
gzclose($zd);

echo $unzipped_content;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接