2011-08-09 15 views
7

He usado TJcl7zCompressArchive/TJcl7zDecompressArchive para hacer operaciones de archivo antes.Can Delphi JCL 7zCompression se usa para comprimir/descomprimir secuencias en memoria sin operaciones de archivos?

Ahora me gustaría comprimir/descomprimir las secuencias en la memoria directamente sin la operación de archivos. Sin embargo, al ver los ejemplos de demostraciones de JCL que buscan en la web, no puedo encontrar una manera de hacerlo utilizando esa lib. Encontré otras herramientas para hacerlo, pero la relación de compresión no parece tan buena como 7zip.

¿Alguien puede dar algunas instrucciones o muestra el código que muestra cómo lograr esto. ¡Muchas gracias!

+0

¿La envoltura DLL 7z incluyen funcionalidad arroyo o devoluciones de llamada de alguna manera? –

+0

Hay instream/outstream, así como algunos objetos de devolución de llamada. Sin embargo, no puedo entender cómo y es posible usarlos directamente sin usar esos objetos Achieve de alto nivel. – Justmade

Respuesta

10

Utilizo el contenedor JCL para comprimir un flujo GZIP - no estoy seguro de si funcionaría simplemente con un TJcl7ziCompresspArchive. Para comprimir una corriente utilizo el siguiente:

procedure _CompressStreamGZIP(const ASourceStream, ADestinationStream: TStream); 
var 
    LArchive : TJclCompressArchive; 
begin 
    ADestinationStream.Position := 0; 
    ASourceStream.Position := 0; 
    LArchive := TJclGZipCompressArchive.Create(ADestinationStream, 0, False); 

    try 
    LArchive.AddFile('..\Stream.0', ASourceStream, false); 
    LArchive.Compress(); 
    finally 
    if (Assigned(LArchive)) then FreeAndNil(LArchive); 
    end; 
end; 

para descomprimir la corriente:

procedure _DecompressStreamGZIP(const ASourceStream, ADestinationStream : TStream); 
var 
    LArchive : TJclDecompressArchive; 
begin 
    ADestinationStream.Position := 0; 
    ASourceStream.Position := 0; 
    LArchive := TJclGZipDecompressArchive.Create(ASourceStream, 0, false); 

    try 
    LArchive.ListFiles(); 
    LArchive.Items[0].Stream := ADestinationStream; 
    LArchive.Items[0].OwnsStream := false; 
    LArchive.Items[0].Selected := True; 
    LArchive.ExtractSelected(); 
    finally 
    if (Assigned(LArchive)) then FreeAndNil(LArchive); 
    end; 
end; 
+0

¡Perfecto! ¡Probé cambiando el Gzip a 7z y funciona como un hechizo! ¡Muchas gracias! – Justmade

+3

Deberías mover las primeras tres líneas en el bloque TRY/FINALLY fuera del TRY. En caso de que se produzca un error en el constructor .Create y se produzca una excepción, LArchive no está asignado (y no es NIL) y luego intenta liberar una instancia de clase no asignada. SIEMPRE coloque la llamada al constructor JUSTO antes de que el bloque TRY/FINALMENTE libere. Además, no es necesario que haga una prueba para Assigned (LArchive) cuando llame a FreeAndNIL, ya que esta prueba se realiza dentro del procedimiento FreeAndNIL. – HeartWare

Cuestiones relacionadas