gzdeflate () e una grande quantità di dati
Domanda
Ho creato una classe per creare file ZIP in PHP. Un'alternativa a ZipArchive presupponendo che non sia consentita nel server. Qualcosa da usare con quei server gratuiti.
Sta già funzionando, crea le strutture ZIP con PHP e usa gzdeflate () per generare i dati compressi.
Il problema è che gzdeflate () mi richiede di caricare l'intero file in memoria e voglio che la classe funzioni limitata a 32 MB di memoria. Attualmente sta archiviando file di dimensioni superiori a 16 MB senza alcuna compressione.
Immagino che dovrei farlo comprimere i dati in blocchi, 16 MB per 16 MB, ma non so come concatenare il risultato di due gzdeflate ().
L'ho provato e sembra che richieda un po 'di matematica negli ultimi 16 bit, una sorta di buff- > last16bits = (buff- > last16bits & amp; newblock- > first16bits) | 0xfffe
, funziona, ma non per tutti gli esempi ...
Domanda: come concatenare due flussi DEFLATEd senza decomprimerlo?
Soluzione
I filtri di flusso PHP vengono utilizzati per eseguire tali attività. stream_filter_append
può essere utilizzato durante la lettura o la scrittura su stream. Ad esempio
$fp = fopen($path, 'r');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_READ);
Ora fread
ti restituirà dati sgonfiati.
Altri suggerimenti
Questo può o meno aiutare. Sembra che gzwrite ti permetta di scrivere file senza averli completamente caricati in memoria. Questo esempio dalla pagina del manuale di PHP mostra come comprimere un file usando gzwrite e fopen.
http://us.php.net/manual/en/function .gzwrite.php
function gzcompressfile($source,$level=false){
// $dest=$source.'.gz';
$dest='php://stdout'; // This will stream the compressed data directly to the screen.
$mode='wb'.$level;
$error=false;
if($fp_out=gzopen($dest,$mode)){
if($fp_in=fopen($source,'rb')){
while(!feof($fp_in))
gzwrite($fp_out,fread($fp_in,1024*512));
fclose($fp_in);
}
else $error=true;
gzclose($fp_out);
}
else $error=true;
if($error) return false;
else return $dest;
}