2012-01-17 9 views
7

Czy są jakieś elementy zip z takimi funkcjami? Muszę pobrać archiwum zip z Internetu do strumienia, a następnie otworzyć archiwum ze strumienia, a następnie wyodrębnić pliki do innego strumienia.Delphi: otwórz archiwum zip ze strumienia -> wypakuj do strumienia

E.g. ZipForge może otworzyć archiwum ze strumienia ZipForge.OpenArchive(MyStream, false); , ale jak wyodrębnić do innego ...?

procedure ExtractToStream(FileName: WideString; Stream: TStream); 

Opis

Zastosowanie ExtractToStream do dekompresji danych przechowywanych w pliku wewnątrz archiwum do obiektu TStream potomka jak TFileStream, TMemoryStream lub TBlobStream.

Parametr FileName określa wyodrębnioną nazwę pliku.

A jakie zastosowanie metody OpenArchive(MyStream, false) jeśli wydobycie nie jest obsługiwany ...

Odpowiedz

19

Komponent plik zip, który jest wbudowany w XE2 będzie to zrobić.

Istnieje przeciążona metoda Open, która odbiera TStream jako parametry wejściowe.

Aby wyodrębnić pojedyncze pliki, można wywołać przeciążoną metodę Read przekazującą nazwę pliku, który ma zostać wyodrębniony. Wyodrębniony plik jest zwracany jako nowe wystąpienie TStream. Możesz użyć tej CopyFrom na tej instancji, aby przesłać wyodrębniony plik do strumienia.

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; 

pamiętać, że nie zostały przetestowane ten kod, właśnie napisane jest na podstawie kodu źródłowego TZipFile oraz dokumentacji zawartej w tym kodzie źródłowym. Może być w tym kilka zmarszczek, ale jeśli kod zachowuje się tak, jak jest reklamowany, idealnie spełnia twoje potrzeby.


OK, teraz przetestowałem to, ponieważ byłem ciekawy. Oto program, który pokazuje, że wszystko działa jak reklamowane:

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. 

pamiętać, że ekstrakcji przez indeks zamiast nazwy pliku, ponieważ to było bardziej wygodne dla mnie. Użyłem raczej strumieni plików, a nie strumieni pamięci, które, jak sobie wyobrażam, wykorzystają. Jednakże, ponieważ metody TZipFile działają z TStream jestem pewien, że kod będzie działał ze strumieniami dowolnej postaci.


To jest najnowszy z serii pytań dotyczących plików ZIP. Wiem, że używasz XE2 i zastanawiam się, dlaczego wydajesz się niechętny do korzystania z wbudowanej klasy ZIP, którą zapewnia XE2. Nie widziałem niczego, co wskazywałoby, że nie spełni twoich wymagań. W rzeczywistości właśnie ta zdolność do pracy bezpośrednio ze strumieniami sprawia, że ​​czuję, że ma wystarczającą ogólność dla każdego zastosowania.

+1

Wielkie dzięki David! – maxfax

+0

Nie widziałem metody Read (sprawdziłem szybko), istnieją tylko informacje na jej temat http://docwiki.embarcadero.com/VCL/en/System.Zip.TZipFile.Przeczytaj – maxfax

+0

@maxfax Jakie masz wydanie Delphi? Mam Pro i pochodzi ze źródła. Moje odpowiedzi na twoje ostatnie pytania ZIP są całkowicie oparte na lekturze źródła. Nie wiem dokładnie nic o plikach ZIP i nic o tym komponencie. Jeśli masz kod źródłowy, to będzie to dla mnie ogromna pomoc. –