GZipStream 读取超出我的数据部分的末尾
GZipStream reads beyond the end of my data parts
我的程序通过 HttpWebRequest 下载一个文件,该文件由几个串起来的 gzip 压缩文件组成 files/parts。
因此,当我解压缩我的 responseStream 时,GZipStream 在每个文件部分后自行关闭。这不是一个大问题,因为我可以为每个文件创建一个新文件,但问题是:GZipStream 读取超出每个文件的范围,即下一个文件的开头。
这是个问题,因为我不能将 Seek() 应用到我的 responseStream 到 return 到下一个文件的偏移量,所以下一个文件基本上丢失了。
对我来说最明显的解决方案是在解压之前将 NetworkStream 复制到 MemoryStream 中。但我不希望将整个文件加载到内存中,甚至不希望将文件部分加载到内存中,只需要定义的缓冲区大小 (f.e.512kB).
==================已编辑====================
我的新解决方案,感谢 Tarik
============================================
下载过程:
using (DownloadStream dlStream = new DownloadStream(responseStream, file.compressedSize))
using (GZipStream zip = new GZipStream(dlStream, CompressionMode.Decompress, true))
{
await zip.CopyToAsync(fs);
}
下载流class:
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 这个简单的解决方案! :)
我会创建一个实现流的 class。我将向此 class 构造函数传递响应流和它在指示 EOF 之前应读取的数据大小。在内部,此流将从底层响应流读取,并在达到指定限制时停止读取。
我会实例化这些流 classes,一次一个,具有所需的大小,并将它们传递给 GZipStream。
我的程序通过 HttpWebRequest 下载一个文件,该文件由几个串起来的 gzip 压缩文件组成 files/parts。
因此,当我解压缩我的 responseStream 时,GZipStream 在每个文件部分后自行关闭。这不是一个大问题,因为我可以为每个文件创建一个新文件,但问题是:GZipStream 读取超出每个文件的范围,即下一个文件的开头。
这是个问题,因为我不能将 Seek() 应用到我的 responseStream 到 return 到下一个文件的偏移量,所以下一个文件基本上丢失了。
对我来说最明显的解决方案是在解压之前将 NetworkStream 复制到 MemoryStream 中。但我不希望将整个文件加载到内存中,甚至不希望将文件部分加载到内存中,只需要定义的缓冲区大小 (f.e.512kB).
==================已编辑====================
我的新解决方案,感谢 Tarik
============================================
下载过程:
using (DownloadStream dlStream = new DownloadStream(responseStream, file.compressedSize))
using (GZipStream zip = new GZipStream(dlStream, CompressionMode.Decompress, true))
{
await zip.CopyToAsync(fs);
}
下载流class:
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 这个简单的解决方案! :)
我会创建一个实现流的 class。我将向此 class 构造函数传递响应流和它在指示 EOF 之前应读取的数据大小。在内部,此流将从底层响应流读取,并在达到指定限制时停止读取。 我会实例化这些流 classes,一次一个,具有所需的大小,并将它们传递给 GZipStream。