2010-07-16 60 views
6

较大的文件我试图解压到PHP的14MB归档与这样的代码:解压用PHP

$zip = zip_open("c:\kosmas.zip"); 
    while ($zip_entry = zip_read($zip)) { 
    $fp = fopen("c:/unzip/import.xml", "w"); 
    if (zip_entry_open($zip, $zip_entry, "r")) { 
    $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); 
    fwrite($fp,"$buf"); 
    zip_entry_close($zip_entry); 
    fclose($fp); 
    break; 
    } 
    zip_close($zip); 
    } 

它无法在我的本地与经典的“Allowed memory size of blablabla bytes exhausted” 128MB内存限制。在服务器上,我有16MB的限制,有没有更好的方法来做到这一点,以便我可以适应这个限制?我不明白为什么要分配超过128MB的内存。提前致谢。

解决方案: 我开始读取10Kb块中的文件,问题解决了内存使用峰值arnoud 1.5MB。

 $filename = 'c:\kosmas.zip'; 
     $archive = zip_open($filename); 
     while($entry = zip_read($archive)){ 
      $size = zip_entry_filesize($entry); 
      $name = zip_entry_name($entry); 
      $unzipped = fopen('c:/unzip/'.$name,'wb'); 
      while($size > 0){ 
       $chunkSize = ($size > 10240) ? 10240 : $size; 
       $size -= $chunkSize; 
       $chunk = zip_entry_read($entry, $chunkSize); 
       if($chunk !== false) fwrite($unzipped, $chunk); 
      } 

      fclose($unzipped); 
     } 
+0

什么是zip文件的* uncompressed *大小? – 2010-07-16 08:30:08

+0

是否使用命令行工具选项? – 2010-07-16 08:30:47

+0

未压缩的大小约为110MB。 不幸的是,使用命令行不是一个选项。 – cypher 2010-07-16 08:32:15

回答

4

为什么你一次读完整个文件?

$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); 
fwrite($fp,"$buf"); 

尝试读它的小块,并将其写入文件。

+0

这正是我所做的,如果有人感兴趣,我会在一分钟内发布解决方案。 – cypher 2010-07-16 08:53:51

1

仅仅因为一个zip小于PHP的内存限制&也许是解压的那样好,不考虑PHP的开销通常更重要的是所需要的内存实际解压缩文件,而我我没有压缩专家,我预计可能会比最终解压缩的大小多很多。

+0

是的,但似乎总有一种替代方案,即我可以使用峰值内存使用量低于1MB的更大的归档文件,我可以解析1.5GB xml文件,峰值内存使用量低于3MB,为什么不能有这种替代方案对于zip文件... – cypher 2010-07-16 08:37:26

0

对于大小的文件,或许是更好,如果你使用shell_exec()代替:

shell_exec('unzip archive.zip -d /destination_path'); 

PHP必须在安全模式下运行,你必须同时访问了shell_exec并解压这个方法工作。

更新

鉴于命令行工具是不可用的,所有我能想到的是创建一个脚本,并将文件发送到命令行工具可用的远程服务器上,解文件并下载内容。

+0

不幸的是,命令行工具被服务器禁用。 – cypher 2010-07-16 08:38:36

+0

@Anax这就是为什么PHP得到一个不好的包装。为什么生产应用程序需要运行命令行参数?这是许多PHP蠕虫的主要来源。 – 2012-08-04 17:46:41

0
function my_unzip($full_pathname){ 

    $unzipped_content = ''; 
    $zd = gzopen($full_pathname, "r"); 

    while ($zip_file = gzread($zd, 10000000)){ 
     $unzipped_content.= $zip_file; 
    } 

    gzclose($zd); 

    return $unzipped_content; 

} 
+1

此解决方案背后的任何解释或推理可能有助于理解问题。 – PiotrWolkowski 2014-07-07 00:02:37

+0

此外,这已被** 4 **年前回答。 – cypher 2014-07-07 17:46:41