【前言】
写这个教程的原因,是因为要实现下面的场景:
1、通过 THttpClient 从网络上下载压缩包到内存流中。
2、将内存流中的 ZIP 格式压缩数据中的特定扩展名文件,在内存中直接解压处理,而不是解压到磁盘,再加载。
【实现流程】
1、下载压缩包到内存流中,这个本身直接通过 THttpClient.Get 或 BeginGet 就可以实现,注意 BeginGet 是异步操作,需要在回调中调用 EndAsynHttp 以便触发可能的异常。
var
AResp: IHttpResponse;
AStream: TFileStream;
begin
try
AResp := FHTTPClient.EndAsyncHTTP(ASyncResult);
AStream:=AResp.ContentStream;
...
2、IHttpResponse.ContentStream 就是我们需要的内存流对象,下面是真正的代码工作时间:
- 第一步:需要确定流格式的有效性。System.Zip.TZipFile 类提供了 IsValid 函数来做这一判断。
- 第二步:将源内存流的位置调整到开始,然后创建 TZipFile 实例,并调用 Open 方法,打开这一内存流。
- 第三步:通过 TZipFile.FileCount 和 TZipFile.FileNames 属性,来找到内存流中特定扩展名的文件。
- 第四步:找到文件后,调用 TZipFile.Read 来获取解压后的数据流对象。
- 第五步:从返回的流中加载数据
if TZipFile.IsValid(AStream) then
begin
AStream.Position := 0;
AZip := TZipFile.Create;
AZip.Open(AStream, TZipMode.zmRead);
for I := 0 to AZip.FileCount - 1 do
begin
if LowerCase(ExtractFileExt(AZip.FileNames[I])) = '.json' then
begin
AZip.Read(I, AJsonStream, AHeader);
try
//这里是实际处理流中数据代码,AJsonStream 不需要预先创建
AJson.LoadFromStream(AJsonStream);
finally
FreeAndNil(AJsonStream);
end;
break;
end;
end;
end