我的程序通过HttpWebRequest下载一个文件,其中包含几个经过压缩的gzip压缩文件/部分。GZipStream超出我的数据部分末尾
所以当我解压缩我的responseStream时,GZipStream在每个文件部分之后关闭。这不是一个大问题,因为我可以为每个文件创建一个新的文件,但问题是:GZipStream读取每个文件之外,即下一个文件的开始。
这是一个问题,因为我无法将Seek()应用到我的responseStream以返回到下一个文件的偏移量,所以这个下一个文件基本上丢失了。
对我来说最明显的解决方案是在解压缩之前将NetworkStream复制到MemoryStream中。但我不希望整个文件加载到内存中,甚至不是文件部分,只有定义的缓冲区大小(f.e. 512kB)。
================== EDITED ====================
我的新解决方案,谢谢塔里克
======================================== ====
下载Process:
using (DownloadStream dlStream = new DownloadStream(responseStream, file.compressedSize))
using (GZipStream zip = new GZipStream(dlStream, CompressionMode.Decompress, true))
{
await zip.CopyToAsync(fs);
}
DownloadStream类:
class DownloadStream : Stream
{
Stream strm;
int len;
int pos;
public DownloadStream(Stream netStream, int fileSize)
{
strm = netStream;
len = fileSize;
pos = 0;
}
public override int Read(byte[] buffer, int offset, int count)
{
int rest = len - pos;
int nRead;
if (count > rest)
{
nRead = strm.Read(buffer, 0, rest);
}
else
{
nRead = strm.Read(buffer, 0, count);
}
pos += nRead;
return nRead;
}
public override bool CanRead
{
get
{
return true;
}
}
//...add all other must-overrideables throwing NotImplementedException.
}
这就是我所需要的。正如人们所看到的,它也支持异步解压缩任务,并且几乎不使用内存。 非常感谢你这个简单的解决方案塔里克! :)
你能预先确定每个压缩文件的大小吗? – Tarik 2015-02-10 19:43:53
当然,当您查看代码时,会有file.compressedSize。此外,我还保存了流内文件部分的所有偏移量/查找点以及未压缩的大小。 – Showdown 2015-02-10 19:48:01