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。