我的程序通过HttpWebRequest下载一个文件,该文件由几个stringed up gzip压缩文件/部分组成。
因此,当我解压缩responseStream时,GZipStream会在每个文件部分后自行关闭。这不是一个大问题,因为我可以为每个文件创建一个新文件,但问题是:GZipStream读取每个文件,即下一个文件的开头。
这是一个问题,因为我不能将Seek()应用到我的responseStream来返回下一个文件的偏移量,所以下一个文件基本上就丢失了。
对我来说最明显的解决方案是在解压缩之前将NetworkStream复制到MemoryStream中。但我不希望将整个文件加载到内存中,甚至不是文件部分,只需要定义的缓冲区大小(f.e.512kB)。
================== EDITED ====================
我的新解决方案,感谢Tarik
============================================
下载流程:
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! :)
答案 0 :(得分:0)
我会创建一个实现流的类。我会在指示EOF之前将响应流及其应读取的数据大小传递给此类构造函数。在内部,此流将从底层响应流中读取,并在达到指定限制时停止读取。 我会一次一个地设置这些流类,并将它们传递给GZipStream。