Ir para conteúdo
Fórum Script Brasil
  • 0

(Des)Compactar com ZLib


McBlade

Pergunta

Saudações Amigos.

Estive lendo o tópico http://scriptbrasil.com.br/forum/index.php?showtopic=91047 e estou utilizando o código para fazer alguns testes de compactação com TCompressionStream e TDecompressionStream da ZLib segundo o código postado retirado do "Torry's Delphi Pages"

O algoritmo funciona apenas quando se tem mais de 1 arquivo compactado. Digo isso porque eu estou tentando descompactar um único mísero arquivo e a linha "infile.Read(c,SizeOf( c )); { number of files }" me retorna um número gigante e na segunda iteração do FOR dá erro de criação de arquivo referenciando o arquivo desta forma: "C:\TEMP\C:\TEMP\TESTE.EXE". Eu deduzo que na segunda iteração o bendito esteja copiando o caminho do arquivo então eu comentei o "S := Dest+S" e adicionei o "Dest" no "outfile := TFileStream.Create(s,fmCreate);" ficando assim "outfile := TFileStream.Create(Dest+s,fmCreate);". Mas mesmo assim ele me retorna um erro, desta vez diferente "Stream read error".

Detalhe Importante: o único arquivo compactado retorna ao seu tamanho original, então porque o algoritmo me retorna erro?

Alguém conseguiu fazer esse código funcionar?

Seguem meus códigos

procedure TForm1.CompressFiles(Files : TStrings; const Filename : String);
var
  InFile, OutFile, TmpFile : TFileStream;
  Compr : TCompressionStream;
  I, L : Integer;
  S : String;
begin
  if Files.Count > 0 then
  begin
    OutFile := TFileStream.Create(Filename,fmCreate);
    try
      { the number of files }
      L := Files.Count;
      OutFile.Write(L,SizeOf(L));
      for I := 0 to Files.Count-1 do
      begin
        InFile := TFileStream.Create(Files[I],fmOpenRead);
        try
          { the original filename }
          S := ExtractFilename(Files[I]);
          L := Length(S);
          OutFile.Write(L,SizeOf(L));
          OutFile.Write(S[1],L);
          { the original filesize }
          L := InFile.Size;
          OutFile.Write(L,SizeOf(L));
          { compress and store the file temporary}
          TmpFile := TFileStream.Create('tmp',fmCreate);
          Compr := TCompressionStream.Create(clMax,TmpFile);
          try
            Compr.CopyFrom(InFile,L);
          finally
            Compr.Free;
            TmpFile.Free;
          end;
          { append the Compressed file to the destination file }
          TmpFile := TFileStream.Create('tmp',fmOpenRead);
          try
            OutFile.CopyFrom(TmpFile,0);
          finally
            TmpFile.Free;
          end;
        finally
          InFile.Free;
        end;
      end;
    finally
      OutFile.Free;
    end;
    DeleteFile('tmp');
  end;
end;

procedure TForm1.DecompressFiles(const Filename, DestDirectory : String);
var
  Dest,S: String;
  Decompr: TDecompressionStream;
  InFile, OutFile: TFilestream;
  I,L,C: Integer;
begin
  Dest   := IncludeTrailingPathDelimiter(DestDirectory);
  InFile := TFileStream.Create(Filename,fmOpenRead);
  try
    { number of files }
    InFile.Read(C,SizeOf(C));
    for I := 1 to C do
    begin
      { read filename }
      InFile.Read(L,SizeOf(L));
      SetLength(S,L);
      InFile.Read(S[1],L);
      { read filesize }
      InFile.Read(L,SizeOf(L));
      { Decompress the files and store it }
      S := Dest+S; //include the path
      OutFile := TFileStream.Create(Dest+S,fmCreate);
      Decompr := TDecompressionStream.Create(InFile);
      try
        OutFile.CopyFrom(Decompr,L);
      finally
        OutFile.Free;
        Decompr.Free;
      end;
    end;
  finally
    InFile.Free;
  end;
end;

Link para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

  • 0
Estive lendo o tópico http://scriptbrasil.com.br/forum/index.php?showtopic=91047 e estou utilizando o código para fazer alguns testes de compactação com TCompressionStream e TDecompressionStream da ZLib segundo o código postado retirado do "Torry's Delphi Pages"

O algoritmo funciona apenas quando se tem mais de 1 arquivo compactado. Digo isso porque eu estou tentando descompactar um único mísero arquivo e a linha "infile.Read(c,SizeOf( c )); { number of files }" me retorna um número gigante e na segunda iteração do FOR dá erro de criação de arquivo referenciando o arquivo desta forma: "C:\TEMP\C:\TEMP\TESTE.EXE".

McBlade, mas se há um único arquivo dentro deste zip, como poderia estar havendo uma segunda interação?

Eu estou sem tempo para dar um help nisto, mas haveria alguma possibilidade de o arquivo zipado conter contém o path junto ao nome do arquivo sendo descompactado? Há alguma possibilidade de o arquivo de origem não ter sido gerado pela sua rotina de compactação (a qual não guarda o path, pelo que vejo)?

Se você souber utilizar o depurador, você provavelmente conseguirá achar o problema. Ponha um break-point (F5) no início da interação e acompanhar o valor das variáveis via eveluate (CTRL+F7).

Abraços

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...