Delphi:从流中打开一个zip存档->提取到流 [英] Delphi: open a zip archive from a stream -> extract to a stream
问题描述
是否有任何具有此类功能的zip组件?我需要从Internet将zip存档下载到流中,然后从流中打开存档,然后将文件提取到另一个流中.
Are there any zip components with such features? I need to download a zip archive from the Internet to a stream, then to open the archive from the stream and then to extract files to another stream.
例如 ZipForge 可以从流ZipForge.OpenArchive(MyStream, false);
中打开档案
但是如何提取到另一个...?
E.g. ZipForge can open an archive from a stream ZipForge.OpenArchive(MyStream, false);
but how to extract to another one...?
procedure ExtractToStream(FileName: WideString; Stream: TStream);
说明
使用ExtractToStream解压缩存储在文件内部的数据 存档到TStream后代对象,如TFileStream,TMemoryStream 或TBlobStream.
Use ExtractToStream to decompress data stored in the file inside the archive to a TStream descendant object like TFileStream, TMemoryStream or TBlobStream.
FileName参数指定要提取的文件名.
The FileName parameter specifies file name being extracted.
如果不支持提取,OpenArchive(MyStream, false)
方法有什么用...
And what use of the OpenArchive(MyStream, false)
method if extraction isn't supported...
推荐答案
XE2中内置的zip文件组件将执行此操作.
The zip file component that is built into XE2 will do this.
有一个重载的Open
方法,该方法接收TStream
作为其输入参数.
There is an overloaded Open
method that receives a TStream
as its input parameters.
要提取单个文件,可以调用重载的Read
方法,并传递要提取的文件名.提取的文件作为TStream
的新实例返回.您可以在该实例上使用CopyFrom
将提取的文件传输到流中.
To extract individual files you can call an overloaded Read
method passing the name of the file that you wish to extract. The extracted file is returned as a new instance of TStream
. You can that use CopyFrom
on that instance to transfer the extracted file to your stream.
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
的源代码和该源代码中包含的文档编写了该代码.可能会有一些折痕,但是如果代码的行为与所宣传的一样,则可以完全满足您的需求.
Note that I've not tested this code, I've just written it based on the source code for TZipFile
and the documentation contained in that source code. There may be a few wrinkles in this but if the code behaves as advertised it meets your needs perfectly.
好的,现在我进行了测试,因为我很好奇.这是表明这一切如广告所示的程序:
OK, now I tested it because I was curious. Here's the program that shows that this all works as advertised:
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
一起使用,所以我确定代码可以与任何形式的流一起使用.
Note that I extracted by index rather than file name since that was more convenient for me. And I used file streams rather than memory streams which I imagine you would use. However, since the TZipFile
methods work with TStream
I'm sure that the code will work with streams of any form.
这是有关ZIP文件的一系列问题中的最新问题.我知道您正在使用XE2,但我想知道为什么您似乎不愿意使用XE2提供的内置ZIP类.我没有看到任何迹象表明它将无法满足您的要求.实际上,正是这种直接使用流的能力使我感到它对于任何应用程序都具有足够的通用性.
This is the latest in a series of questions about ZIP files. I know that you are using XE2 and I wonder why you seem reluctant to use the built in ZIP class that XE2 provides. I've not seen anything to indicate that it will not fulfil your requirements. In fact, it is precisely this ability to work directly with streams that makes me feel it has sufficient generality for any application.
这篇关于Delphi:从流中打开一个zip存档->提取到流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!