2011-08-09 13 views
7

Użyłem TJcl7zCompressArchive/TJcl7zDecompressArchive do wykonania operacji archiwizacji wcześniej.Czy Delphi JCL 7zCompression może kompresować/dekompresować strumień w pamięci bez operacji na plikach?

Teraz chciałbym kompresować/dekompresować strumienie w pamięci bezpośrednio bez operacji na plikach. Jednak widząc przykłady z dem wyszukiwania JCL w Internecie, nie mogę znaleźć sposobu, aby to zrobić za pomocą tej biblioteki. Znalazłem inne narzędzia do tego, ale współczynnik kompresji nie wydaje się tak dobry jak 7zip.

Czy ktoś może podać wskazówki lub przykładowy kod pokazujący, jak to osiągnąć. Wielkie dzięki!

+0

Czy 7z dll otoki zawiera funkcji strumienia lub wywołania zwrotne jakoś? –

+0

Istnieje instream/outstream, a także niektóre obiekty wywołania zwrotnego. Nie mogę jednak dowiedzieć się, jak i czy można z nich korzystać bezpośrednio, bez korzystania z obiektów o wysokim poziomie. – Justmade

Odpowiedz

10

Używam wrapper JCL do kompresji strumienia GZIP - nie jestem pewien, czy to działa po prostu za pomocą TJcl7ziCompresspArchive. Do kompresji strumienia używam następujący:

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; 

do dekompresji strumienia:

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

Idealny! Testowałem zmianę Gzip na 7z i działa jak urok! Dziękuję Ci bardzo! – Justmade

+3

Powinieneś przesunąć pierwsze trzy linie w wierszu TRY/FINALLY poza TRY. W przypadku wystąpienia błędu w konstrukcie .Create i wyjątku jest podniesiony, LArchiwum jest nieprzypisane (i nie jest NIL), a następnie spróbuj zwolnić nieprzydzielone wystąpienie klasy. ZAWSZE umieść wywołanie do konstruktora JUST przed blokiem TRY/FINALLY, który jest zwalniany. Ponadto - nie musisz testować dla Assigned (LArchive) podczas wywoływania FreeAndNIL, ponieważ ten test jest wykonywany wewnątrz procedury FreeAndNIL. – HeartWare

Powiązane problemy