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.
Wielkie dzięki David! – maxfax
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
@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. –