Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi:从流中打开zip存档->;提取到溪流中_Delphi_Stream_Load_Zip_Extract - Fatal编程技术网

Delphi:从流中打开zip存档->;提取到溪流中

Delphi:从流中打开zip存档->;提取到溪流中,delphi,stream,load,zip,extract,Delphi,Stream,Load,Zip,Extract,是否有具有此类功能的zip组件?我需要从Internet下载一个zip存档到一个流,然后从该流打开存档,然后将文件解压缩到另一个流 例如,ZipForge可以从流ZipForge.OpenArchive打开存档(MyStream,false) 但如何提取到另一个 procedure ExtractToStream(FileName: WideString; Stream: TStream); 说明 使用ExtractToStream解压存储在 存档到TStream子体对象,如TFileStr

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

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

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

使用ExtractToStream解压存储在 存档到TStream子体对象,如TFileStream、TMemoryStream 或者是一条小溪

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


如果提取不受支持,
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类。我没有看到任何迹象表明它不能满足你的要求。事实上,正是这种直接处理流的能力让我觉得它对任何应用程序都有足够的通用性。

我没有看到Read方法(我快速检查),这里有关于它的纯信息@maxfax您有什么版本的Delphi?我有专业的,这是来源。我对你最近两个ZIP问题的回答完全基于阅读资料来源。我对ZIP文件和这个组件一无所知。如果您有源代码,那么我认为这将对您有很大帮助。由于您的示例,刚刚成功地删除了ZipForge依赖项。:)关于这一点,请注意(在XE8中)如果您试图使用.Read()将其提取到流中,那么使用STORE方法放入ZIP的任何内容的大小都将是错误的。据我所知,这是报告(QC 115388),但在输入此注释时,QC已停止。对我来说,这是一个杀手锏,我必须使用不同的Zip包。当我试图解压缩包含子文件的Zip文件时,这对我来说并没有预期的效果。它只生成一个与目标目录同名的文件。