2012-01-17 27 views
7

Có bất kỳ thành phần zip nào có các tính năng như vậy không? Tôi cần tải xuống lưu trữ zip từ Internet vào luồng, sau đó mở tệp lưu trữ từ luồng và sau đó trích xuất tệp sang luồng khác.Delphi: mở lưu trữ zip từ luồng -> trích xuất thành luồng

Ví dụ: ZipForge có thể mở tệp lưu trữ từ luồng ZipForge.OpenArchive(MyStream, false); nhưng cách trích xuất một tệp khác ...?

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

Mô tả

Sử dụng ExtractToStream để giải nén dữ liệu được lưu trữ trong các tập tin bên trong các kho lưu trữ đến một đối tượng TStream hậu duệ như TFileStream, TMemoryStream hoặc TBlobStream.

Tham số FileName chỉ định tên tệp được trích xuất.

Và những gì sử dụng các phương pháp OpenArchive(MyStream, false) nếu khai thác không được hỗ trợ ...

Trả lời

19

Các thành phần tập tin zip có được xây dựng vào XE2 sẽ làm điều này.

Có phương thức quá tải Open nhận được thông số đầu vào TStream.

Để trích xuất các tệp riêng lẻ, bạn có thể gọi phương thức quá tải Read chuyển tên của tệp mà bạn muốn trích xuất. Tệp được giải nén được trả về dưới dạng phiên bản mới của TStream. Bạn có thể sử dụng CopyFrom trên trường hợp đó để chuyển tệp được trích xuất sang luồng của bạ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; 

Lưu ý rằng tôi đã không kiểm tra mã này, tôi vừa viết mã này dựa trên mã nguồn cho TZipFile và tài liệu chứa trong mã nguồn đó. Có thể có một vài nếp nhăn trong điều này nhưng nếu mã hoạt động như quảng cáo, nó đáp ứng nhu cầu của bạn một cách hoàn hảo.


OK, bây giờ tôi đã thử nghiệm vì tôi tò mò. Đây là chương trình cho thấy rằng tất cả điều này hoạt động như được quảng cáo:

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. 

Lưu ý rằng tôi trích xuất theo chỉ mục thay vì tên tệp vì điều đó thuận tiện hơn cho tôi. Và tôi đã sử dụng luồng tệp thay vì luồng bộ nhớ mà tôi tưởng tượng bạn sẽ sử dụng. Tuy nhiên, vì phương thức TZipFile hoạt động với TStream Tôi chắc chắn rằng mã sẽ hoạt động với các luồng của bất kỳ biểu mẫu nào.


Đây là câu hỏi mới nhất trong loạt câu hỏi về tệp ZIP. Tôi biết rằng bạn đang sử dụng XE2 và tôi tự hỏi tại sao bạn dường như miễn cưỡng sử dụng được xây dựng trong lớp ZIP mà XE2 cung cấp. Tôi đã không thấy bất cứ điều gì để chỉ ra rằng nó sẽ không đáp ứng yêu cầu của bạn. Trong thực tế, chính xác là khả năng này làm việc trực tiếp với các luồng khiến tôi cảm thấy nó có đủ tính tổng quát cho bất kỳ ứng dụng nào.

+1

Cảm ơn rất nhiều David !!! – maxfax

+0

Tôi không thấy phương thức Đọc (tôi đã kiểm tra nhanh), có thông tin thuần túy về nó http://docwiki.embarcadero.com/VCL/en/System.Zip.TZipFile.Đọc – maxfax

+0

@maxfax Bạn có phiên bản Delphi nào? Tôi đã có Pro và đi kèm với nguồn. Câu trả lời của tôi cho cả hai câu hỏi ZIP gần đây của bạn dựa hoàn toàn vào việc đọc nguồn. Tôi biết chính xác không có gì về các tập tin ZIP và không có gì về thành phần này. Nếu bạn có mã nguồn thì đó sẽ là một trợ giúp lớn cho bạn tôi nghĩ. –

Các vấn đề liên quan