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

max*_*fax 7 delphi zip load extract stream

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

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

procedure ExtractToStream(FileName: WideString; Stream: TStream); 
Run Code Online (Sandbox Code Playgroud)

描述

使用ExtractToStream将存档内文件中存储的数据解压缩到Tileream后代对象,如TFileStream,TMemoryStream或TBlobStream.

FileName参数指定要提取的文件名.

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

Dav*_*nan 22

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

有一个重载Open方法接收a 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;
Run Code Online (Sandbox Code Playgroud)

请注意,我没有测试过这段代码,我刚刚根据源代码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.
Run Code Online (Sandbox Code Playgroud)

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


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