2010-07-16 15 views
6

Sto cercando di decomprimere un archivio 14MB con PHP con codice come questo:Decompressione file più grandi con 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); 
    } 

Viene a mancare sul mio localhost con il limite di 128 MB di memoria con il classico "Allowed memory size of blablabla bytes exhausted". Sul server, ho un limite di 16MB, c'è un modo migliore per farlo in modo che possa rientrare in questo limite? Non vedo perché questo deve allocare più di 128 MB di memoria. Grazie in anticipo.

Soluzione: ho iniziato a leggere i file in blocchi 10kb, problema risolto con la memoria di picco utilizzo 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

Qual è la dimensione * non compressa * del file zip? –

+0

È possibile utilizzare gli strumenti della riga di comando? –

+0

La dimensione non compressa è di circa 110 MB. Sfortunatamente, usare la riga di comando non è un'opzione. – cypher

risposta

4

Perché leggi l'intero file in una sola volta?

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

Cerca di leggere piccoli pezzi e di scriverli in un file.

+0

Questo è esattamente quello che ho fatto e pubblicherò la soluzione tra un minuto, se qualcuno è interessato. – cypher

1

Solo perché una zip è inferiore al limite di memoria del PHP & forse il decompresso è così, non tiene conto delle spese generali di PHP in generale e soprattutto la memoria necessaria per realtà decomprimere il file, che mentre io' Non sono esperto di compressione mi aspetto che possa essere molto più grande della dimensione finale decompressa.

+0

Sì, ma sembra esserci sempre un'alternativa, ovvero posso decomprimere un archivio molto più grande con un utilizzo di memoria inferiore a 1 MB, posso analizzare file xml da 1,5 GB con utilizzo di memoria di picco inferiore a 3 MB, perché non potrebbe esserci un'alternativa per file zip ... – cypher

0

Per un file di quelle dimensioni, forse è meglio se si utilizza shell_exec() invece:

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

PHP deve non essere in esecuzione in modalità provvisoria e si deve avere accesso sia shell_exec e decomprimere per questo metodo per lavorare

Aggiornamento:

Dato che gli strumenti della riga di comando non sono disponibili, tutto quello che viene in mente è quello di creare uno script e inviare il file a un server remoto in cui gli strumenti da riga di comando sono disponibili, estrarre il file e scarica il contenuto.

+0

Sfortunatamente, gli strumenti da riga di comando sono disabilitati dal server. – cypher

+0

@Anax questo è il motivo per cui PHP ottiene un involucro negativo. Perché mai un'applicazione di produzione dovrebbe mai eseguire gli argomenti della riga di comando? Questa è la principale fonte di tanti worm PHP. –

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

Qualsiasi spiegazione o ragionamento dietro questa soluzione potrebbe essere utile per comprendere il problema. – PiotrWolkowski

+0

Inoltre, questo è stato risolto ** 4 ** anni fa. – cypher

Problemi correlati