2010-07-16 62 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