Delphi:从流中打开一个zip存档 – >提取到一个流

是否有任何具有此类功能的拉链组件?我需要将一个zip存档从Internet下载到一个流,然后从流中打开存档,然后将文件解压缩到另一个流.

例如. ZipForge可以从流ZipForge.OpenArchive(MyStream,false)打开存档;
但如何提取到另一个……?

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

描述

Use ExtractToStream to decompress data stored in the file inside the
archive to a TStream descendant object like TFileStream, TMemoryStream
or TBlobStream.

The FileName parameter specifies file name being extracted.

如果不支持提取,那么OpenArchive(MyStream,false)方法的用途是什么……

最佳答案
XE2中内置的zip文件组件将执行此操作.

有一个重载的Open方法接收TStream作为其输入参数.

要提取单个文件,可以调用重载的Read方法,传递要提取的文件的名称.提取的文件作为TStream的新实例返回.您可以使用该实例上的CopyFrom将提取的文件传输到您的流中.

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;

请注意,我没有测试过这段代码,我只是根据TZipFile的源代码和源代码中包含的文档编写的.可能会有一些皱纹,但如果代码表现得像宣传的那样,它可以完美地满足您的需求.

好的,现在我测试了它,因为我很好奇.这是一个程序,表明这一切都像宣传的那样工作:

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.

请注意,我通过索引而不是文件名提取,因为这对我来说更方便.我使用文件流而不是内存流,我想你会使用它.但是,由于TZipFile方法适用于TStream,我确信代码可以使用任何形式的流.

这是有关ZIP文件的一系列问题中的最新内容.我知道您正在使用XE2,我想知道为什么您似乎不愿意使用XE2提供的内置ZIP类.我没有看到任何迹象表明它不符合您的要求.实际上,正是这种直接使用流的能力使我觉得它对于任何应用程序都具有足够的通用性.

转载注明原文:Delphi:从流中打开一个zip存档 – >提取到一个流 - 代码日志