Pregunta

He estado creando una clase para crear archivos ZIP en PHP. Una alternativa a ZipArchive suponiendo que no está permitido en el servidor. Algo para usar con esos servidores gratuitos.

Ya está funcionando, construye las estructuras ZIP con PHP y usa gzdeflate () para generar los datos comprimidos.

El problema es que gzdeflate () requiere que cargue todo el archivo en la memoria, y quiero que la clase trabaje limitada a 32 MB de memoria. Actualmente está almacenando archivos de más de 16 MB sin ninguna compresión.

Me imagino que debería hacer que comprima los datos en bloques, 16 MB por 16 MB, pero no sé cómo concatenar el resultado de dos gzdeflate ().

Lo he estado probando y parece que requiere algunos cálculos matemáticos en los últimos 16 bits, una especie de buff- > last16bits = (buff- > last16bits & amp; newblock- > first16bits) | 0xfffe , funciona, pero no para todas las muestras ...

Pregunta: ¿Cómo concatenar dos flujos DEFLATEd sin descomprimirlo?

¿Fue útil?

Solución

Los filtros de flujo PHP se utilizan para realizar tales tareas. Se puede usar stream_filter_append mientras se lee o se escribe en secuencias. Por ejemplo

    $fp = fopen($path, 'r');
    stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_READ);

Ahora fread le devolverá los datos desinflados.

Otros consejos

Esto puede o no puede ayudar. Parece que gzwrite te permitirá escribir archivos sin tenerlos completamente cargados en la memoria. Este ejemplo de la página del Manual de PHP muestra cómo puede comprimir un archivo usando gzwrite y 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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top