El componente archivo zip que se construye en XE2 lo hará.
Hay un método Open
sobrecargado que recibe un TStream
como sus parámetros de entrada.
Para extraer archivos individuales puede llamar a un método Read
sobrecargado que pasa el nombre del archivo que desea extraer. El archivo extraído se devuelve como una nueva instancia de TStream
. Puede usar CopyFrom
en esa instancia para transferir el archivo extraído a la transmisión.
var
ZipFile: TZipFile;
DownloadedStream, DecompressionStream, MyStream: TStream;
LocalHeader: TZipHeader;
...
ZipFile := TZipFile.Create;
try
ZipFile.Open(DownloadedStream, zmRead);
ZipFile.Read('myzippedfile', DecompressionStream, LocalHeader);
try
MyStream.CopyFrom(DecompressionStream, DecompressionStream.Size);
finally
DecompressionStream.Free;
end;
finally
ZipFile.Free;
end;
Tenga en cuenta que yo no he probado este código, acabo de escribir se basa en el código fuente de TZipFile
y la documentación contenida en el código fuente. Puede haber algunas arrugas en esto, pero si el código se comporta como se anuncia, satisface perfectamente sus necesidades.
Bien, ahora lo probé porque tenía curiosidad. Aquí está el programa que muestra que todo esto funciona como se anuncia:
program ZipTest;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.Classes,
System.Zip;
procedure ExtractToFile(
const ZipFileName: string;
const ZippedFileIndex: Integer;
const ExtractedFileName: string
);
var
ZipFile: TZipFile;
DownloadedStream, DecompressionStream, OutputStream: TStream;
LocalHeader: TZipHeader;
begin
DownloadedStream := TFileStream.Create(ZipFileName, fmOpenRead);
try
ZipFile := TZipFile.Create;
try
ZipFile.Open(DownloadedStream, zmRead);
ZipFile.Read(ZippedFileIndex, DecompressionStream, LocalHeader);
try
OutputStream := TFileStream.Create(ExtractedFileName, fmCreate);
try
OutputStream.CopyFrom(DecompressionStream, DecompressionStream.Size);
finally
OutputStream.Free;
end;
finally
DecompressionStream.Free;
end;
finally
ZipFile.Free;
end;
finally
DownloadedStream.Free;
end;
end;
begin
try
ExtractToFile('C:\desktop\test.zip', 0, 'C:\desktop\out.txt');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Tenga en cuenta que extraje de índice en lugar de nombre de archivo, ya que era más conveniente para mí. Y usé secuencias de archivos en lugar de flujos de memoria que imagino que usaría. Sin embargo, dado que los métodos TZipFile
funcionan con TStream
, estoy seguro de que el código funcionará con flujos de cualquier forma.
Ésta es la última de una serie de preguntas sobre archivos ZIP. Sé que está utilizando XE2 y me pregunto por qué parece reacio a utilizar la clase ZIP incorporada que proporciona XE2. No he visto nada que indique que no cumplirá con sus requisitos. De hecho, es precisamente esta capacidad de trabajar directamente con flujos lo que me hace sentir que tiene suficiente generalidad para cualquier aplicación.
Muchas gracias David !!! – maxfax
No vi el método Read (lo comprobé rápidamente), hay información pura al respecto http://docwiki.embarcadero.com/VCL/en/System.Zip.TZipFile.Lee – maxfax
@maxfax ¿Qué edición de Delphi tienes? Tengo Pro y eso viene con la fuente. Mis respuestas a ambas preguntas ZIP recientes se basan completamente en la lectura de la fuente. Sé exactamente nada sobre los archivos ZIP y nada sobre este componente. Si tienes el código fuente, creo que será una gran ayuda para ti. –