Fórum Compactar com zLib #273545
22/03/2005
0
Valew..
Madrick
Curtir tópico
+ 0Posts
22/03/2005
Madrick
Gostei + 0
23/03/2005
Madrick
procedure TForm1.Button1Click(Sender: TObject);
var
FileIni,FileIni2, FileOut: TFileStream;
Zip: TCompressionStream;
begin
FileIni := TFileStream.Create(´C:\Delivery\arquivo1´, fmOpenRead and fmShareExclusive);
FileIni2 := TFileStream.Create(´C:\Delivery\arquivo2, fmOpenRead and fmShareExclusive);
FileOut:=TFileStream.Create(´C:\Delivery\ArqCompact.arq´, fmCreate or fmShareExclusive);
Zip:=TCompressionStream.Create( clMax, FileOut);
Zip.CopyFrom(FileIni, FileIni.Size);
//Zip.CopyFrom(FileIni2, FileIni2.Size);
Zip.Free;
FileOut.Free;
FileIni.Free;
end;
Bom, agora como fazer para esta jossa descompactar os arquivos, separadamente,tipo retornar arquivo1, arquivo2?
Valew
Gostei + 0
23/03/2005
Marcelo Saviski
TMeuZip = packed record NumArquivos: Integer; Arquivos: array[1..NumArquivos] of packed record Len: Integer; //Tamanho FileInName FileInName: string[Len]; //Armazena o nome do Arquivo FileSize: Integer; //Tamanho em Bytes do Arquivo Arquivo: array[1..Filesize] of Byte; //Arquivo Armazenado Fim: Byte = 0; //indica um fim do arquivo, só para verificação end;
O Código da compressão ficou assim:
procedure Comprimir(FileOutName: TFileName; Files: array of TFileName); var FileInName: TFileName; FileIn, FileOut: TFileStream; Zip: TCompressionStream; NumArquivos, I, Len: Integer; begin FileOut := TFileStream.Create(FileOutName, fmCreate or fmShareExclusive); Zip := TCompressionStream.Create( clMax, FileOut); NumArquivos := Length(Files); Zip.Write(NumArquivos, SizeOf(Integer)); try for I := Low(Files) to High(Files) do begin FileIn := TFileStream.Create(Files[I], fmOpenRead and fmShareExclusive); try FileInName := ExtractFileName(Files[I]); Len := Length(FileInName); Zip.Write(Len, SizeOf(Integer)); Zip.Write(FileInName[1], Len); Zip.Write(FileIn.Size, SizeOf(Integer)); Zip.CopyFrom(FileIn, FileIn.Size); Zip.Write(0, 1); finally FileIn.Free; end; end; finally Zip.Free; FileOut.Free; end; end;
Agora vc chama ele passando o Nome de um Arquivo Destino e um array de Arquivos Fontes.
Comprimir(´C:\Delivery\ArqCompact.arq´, [´C:\Delivery\arquivo1´, ´C:\Delivery\arquivo2´]);
Para descompactar,, usando o TDecompressionStream, vc 1º leria um Integer N que informaria o nº de Arquivos comprimidos, depois passaria um loop para descarregar cada um destes N Arquivos, então vc leria outro inteiro que informaria quantos caracteres tem o nome original do arquivo, Alocaria espaço em uma string S com o [color=green:17fc05ab47]SetLength(NomeOriginalArq, NumCaracteres)[/color:17fc05ab47] e leria X bytes (X = nº caracteres) em NomeOriginalArq[1].
Depois leria outro Inteiro X que indicaria o tamanho do Arquivo (descomprimido), então descarregaria esses X Bytes no Arquivo S, por fim, leria mais 1 byte, e verificaria se ele é 0, para fins de verificação.
repita isso N vezes, até que todos os arquivos estejam extraidos.
para descomprimir vai ser sua tarefa fazer. :wink:
PS: eu nunca usei a ZLib antes, então talvez vc tenha que corrigir o código antes, por favor faça isso :)
PS2:Usei a Zlib que encontrei [url=http://www.koders.com/delphi/fidCCBD2263A7E1FD209D24E2924272520B32EF7B05.aspx?s=zlib]aqui[/url], espero que seja a mesma que vc usa
PS3: Não testei.
Gostei + 0
23/03/2005
Madrick
Gostei + 0
23/03/2005
Madrick
try
FileInName := ExtractFileName(Files[I]);
Len := Length(FileInName);
Zip.Write(Len, SizeOf(Integer));
Zip.Write(FileIn.Size,SizeOf(Integer)); [color=red:fc38836f4a]Erro : variable requered[/color:fc38836f4a]
Zip.CopyFrom(FileIn, FileIn.Size);
Zip.Write(FileInName[1], Len);
Zip.Write(0, 1); [color=red:fc38836f4a]Erro : variable requered[/color:fc38836f4a]
finally
FileIn.Free;
E quanto a descompactação naum saquei muito bem como pegar a informação do arquivo para saber quantos arquivos foram compactado, alguem tem mais uma ideia?
Gostei + 0
24/03/2005
Marcelo Saviski
então tem que declarar as variaveis, pensei que era só quando era pra ler os valores
poem lá aonde tá:
[color=green:957f6748e6]NumArquivos, I, Len: Integer; [/color:957f6748e6]
troca por:
[color=green:957f6748e6]NumArquivos, I, Len, Size: Integer;
Fim: Byte[/color:957f6748e6]
e aonde deu erro: mude para:
Size := FileIn.Size; Zip.Write(Size, SizeOf(Integer));
Fim := 0; Zip.Write(Fim, SizeOf(Byte));
Para descomparctar, use como base o código que compacta, mas altere para ao invés de escrever os valores, carregue eles nas variaveis
Gostei + 0
24/03/2005
Madrick
zip.read(Nome, Len) onde len é o tamanho do nome visto acima;
ai ele retorna vazio inaccessible value;
Alguem tem alguma ideia do que pode ser isto;
Obs.: a compactação segue como no modelo pelo marcelo.
Gostei + 0
24/03/2005
Madrick
Estou aberto a sugestões. :D
Gostei + 0
24/03/2005
Madrick
Gostei + 0
26/03/2005
Madrick
Gostei + 0
27/03/2005
Nerdex
[color=red:940e07f001]CommonFileHeader[/color:940e07f001]
Segue code preview...
procedure TZipFile.SaveToFile(const filename: string); var ZipFileStream: TFileStream; i: integer; begin ZipFileStream := TFileStream.Create(filename, fmCreate); try for i := 0 to High(Files) do with Files[i] do begin CentralDirectory[i].RelativeOffsetOfLocalHeader := ZipFileStream.Position; ZipFileStream.Write(LocalFileHeaderSignature, 4); if (LocalFileHeaderSignature = ($04034B50)) then begin ZipFileStream.Write(CommonFileHeader, SizeOf(CommonFileHeader)); ZipFileStream.Write(PChar(filename)^, CommonFileHeader.FilenameLength); ZipFileStream.Write(PChar(extrafield)^, CommonFileHeader.ExtraFieldLength); ZipFileStream.Write(PChar(CompressedData)^, CommonFileHeader.CompressedSize); end; end; EndOfCentralDirectory.OffsetOfStartOfCentralDirectory := ZipFileStream.Position; for i := 0 to High(CentralDirectory) do with CentralDirectory[i] do begin ZipFileStream.Write(CentralFileHeaderSignature, 4); ZipFileStream.Write(VersionMadeBy, 2); ZipFileStream.Write(CommonFileHeader, SizeOf(CommonFileHeader)); ZipFileStream.Write(FileCommentLength, 2); ZipFileStream.Write(DiskNumberStart, 2); ZipFileStream.Write(InternalFileAttributes, 2); ZipFileStream.Write(ExternalFileAttributes, 4); ZipFileStream.Write(RelativeOffsetOfLocalHeader, 4); ZipFileStream.Write(PChar(filename)^, length(filename)); ZipFileStream.Write(PChar(extrafield)^, length(extrafield)); ZipFileStream.Write(PChar(fileComment)^, length(fileComment)); end; with EndOfCentralDirectory do begin EndOfCentralDirSignature := $06054B50; NumberOfThisDisk := 0; NumberOfTheDiskWithTheStart := 0; TotalNumberOfEntriesOnThisDisk := High(Files) + 1; TotalNumberOfEntries := High(Files) + 1; SizeOfTheCentralDirectory := ZipFileStream.Position - OffsetOfStartOfCentralDirectory; ZipfileCommentLength := length(ZipFileComment); end; ZipFileStream.Write(EndOfCentralDirectory, SizeOf(EndOfCentralDirectory)); ZipFileStream.Write(PChar(ZipFileComment)^, length(ZipFileComment)); finally ZipFileStream.Free; end; end;
Autores:
// Nick Naimo <nick@naimo.com> added support for folders on 6/29/2004 (see ´NJN´)
// Marcin Wojda <Marcin@sacer.com.pl> added exceptions and try finally blocks
p.s.: se não achar te mando por e-mail
Gostei + 0
28/03/2005
Marcelo Saviski
procedure Descomprimir(ZipFileName: TFileName; OutDir: string); resourcestring EDecompressionErrorMessage = ´Arquivo ¬s corrompido´; var FileOutName: string; FileIn, FileOut: TFileStream; Zip: TDecompressionStream; NumArquivos, I, Len, Size: Integer; Fim: Byte; begin FileIn := TFileStream.Create(ZipFileName, fmOpenRead and fmShareExclusive); Zip := TDecompressionStream.Create(FileIn); Zip.Read(NumArquivos, SizeOf(Integer)); try for I := 0 to NumArquivos - 1 do begin Zip.Read(Len, SizeOf(Integer)); SetLength(FileOutName, Len); Zip.Read(FileOutName[1], Len); Zip.Read(Size, SizeOf(Integer)); FileOut := TFileStream.Create(IncludeTrailingBackslash(OutDir) + FileOutName, fmCreate or fmShareExclusive); try FileOut.CopyFrom(Zip, Size); finally FileIn.Free; end; Zip.Read(Fim, SizeOf(Byte)); if Fim <> 0 then raise Exception.CreateFmt(EDecompressionErrorMessage, [ZipFileName]); end; finally Zip.Free; FileIn.Free; end; end;
Exemplo:
Descomprimir(´ArquivoComprimido´, ´DiretórioDestino´); Descomprimir(´C:\Arquivo.arq´, ´C:\ArquivoDescomprimido);
Gostei + 0
28/03/2005
Madrick
Gostei + 0
28/03/2005
Marcelo Saviski
Desse do BDN que o Nerdex falou, parece que tem bastante coisa lá, [url=http://cc.borland.com/search/results.aspx?keywords=zlib&prod=1&cat=4¬2c12¬2c14¬2c13¬2c2¬2c3¬2c16¬2c10¬2c15¬2c17¬2c11¬2c18¬2c9¬2c1]link[/url]
Gostei + 0
28/03/2005
Madrick
Esta forma esta acarretando um erro na seguinte linha:
Zip.Read(Fim, SizeOf(Byte));
Nesta linha que captura o dig. verificador está dando um erro de memoria muito louco, já fiz uns teste aqui mais naum identifiquei o porque, no meu codigo tinha ficado assim :
Zip.Read(Buf ,Size);
FileOut.Write(Buf, Size);
Zip.Read(Fim, SizeOf(Byte));
onde buf é um array do tipo Byte.
O problema que este tipo de implementação acarreta fica por conta do tamanho do array, que nã pode ser menor que o tamanho do arquivo a ser descompactado.
Valew. :wink:
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)