C#.NET为什么在解压缩流时需要Stream.Seek

gco*_*828 4 .net c# zip unzip dotnetzip

我正在开发一个项目,我需要能够解压缩流和字节数组以及压缩它们.我正在运行一些单元测试,从流中创建Zip然后解压缩它们,当我解压缩它们时,DonNetZip将它们视为拉链的唯一方法就是我运行streamToZip.Seek(o,SeekOrigin.Begin)streamToZip.Flush().如果我不这样做,我会收到错误" 无法读取阻止,无数据 " ZipFile.Read(stream).

我想知道是否有人能解释为什么会这样.我已经看过一些关于使用它来实际设置相对读取位置的文章,但没有一篇真正解释为什么在这种情况下需要它.

这是我的代码:

压缩对象:

   public Stream ZipObject(Stream data)
    {
        var output = new MemoryStream();
        using (var zip = new ZipFile())
        {
            zip.AddEntry(Name, data);
            zip.Save(output);
            FlushStream(output);
            ZippedItem = output;
        }

        return output;
    }
Run Code Online (Sandbox Code Playgroud)

解压缩对象:

 public List<Stream> UnZipObject(Stream data)
    {
        ***FlushStream(data); // This is what I had to add in to make it work***

        using (var zip = ZipFile.Read(data))
        {
            foreach (var item in zip)
            {
                var newStream = new MemoryStream();
                item.Extract(newStream);
                UnZippedItems.Add(newStream);
            }
        }
        return UnZippedItems;
    }
Run Code Online (Sandbox Code Playgroud)

Flush方法我不得不补充:

    private static void FlushStream(Stream stream)
    {
        stream.Seek(0, SeekOrigin.Begin);
        stream.Flush();
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

当你返回outputZipObject,那个流就在最后 - 你刚刚写完了数据.您需要"回放"它,以便可以读取数据.想象一下,你有一个录像带,刚刚录制了一个程序 - 你需要在观看它之前回放它,对吧?这里完全一样.

我建议自己这样做ZipObject- 我不相信这Flush是必要的.我个人也会使用这个Position房产:

public Stream ZipObject(Stream data)
{
    var output = new MemoryStream();
    using (var zip = new ZipFile())
    {
        zip.AddEntry(Name, data);
        zip.Save(output);
    }
    output.Position = 0;
    return output;
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您对现实世界的类比...正是我所需要的! (2认同)