Pergunta

Estou construindo uma classe para criar arquivos ZIP em PHP.Uma alternativa ao ZipArchive assumindo que não é permitido no servidor.Algo para usar com esses servidores gratuitos.

Já está meio que funcionando, construir as estruturas ZIP com PHP, e usar gzdeflate() para gerar os dados compactados.

O problema é que gzdeflate() exige que eu carregue o arquivo inteiro na memória e quero que a classe funcione limitada a 32 MB de memória.Atualmente ele armazena arquivos maiores que 16 MB sem nenhuma compactação.

Imagino que deveria compactar os dados em blocos, 16MB por 16MB, mas não sei como concatenar o resultado de dois gzdeflate().

Eu estive testando e parece que requer um pouco de matemática nos últimos 16 bits, mais ou menos buff->last16bits = (buff->last16bits & newblock->first16bits) | 0xfffe, funciona, mas não para todas as amostras ...

Pergunta:Como concatenar dois fluxos DEFLATEd sem descompactá-los?

Foi útil?

Solução

Filtros de fluxo PHP são usados ​​para realizar tais tarefas. stream_filter_append pode ser usado durante a leitura ou gravação em fluxos.Por exemplo

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

Agora fread retornará dados deflacionados.

Outras dicas

Isto pode ou não ajudar. Parece que o Gzwrite permitirá que você escreva arquivos sem que eles sejam completamente carregados na memória. Este exemplo da página Manual PHP mostra como você pode comprimir um arquivo 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;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top