【问题标题】:Decompressing .bz2 stream to file in C#在 C# 中将 .bz2 流解压缩到文件
【发布时间】:2012-12-22 00:14:57
【问题描述】:

我在尝试使用 SharpZipLib 库中的 .bz2 内容时遇到了真正的麻烦,而且我无法在其他地方找到任何帮助。

任何帮助或建议将不胜感激,如果有人能指出我可以从中学习的现有解决方案,那就太棒了!

以下是我正在尝试做的事情,但显然它不起作用。目前我遇到的问题是标记线上未处理“EndOfStreamException”。代码有点乱,我以前从来没有尝试过这样的事情......

正如您可能知道的那样,我是在解压缩之前从网上下载的,但我相当确定部分代码可以正常工作。

while ((inputByte = responseStream.ReadByte()) != -1)
{
    using (MemoryStream ms = new MemoryStream())
    {
        using (BinaryWriter writer = new BinaryWriter(ms))
        {
            writer.Write((byte)inputByte);
        }

        using (BZip2InputStream unzip = new BZip2InputStream(ms)) //Exception occurs here
        {
            buffer = new byte[unzip.Length];
            unzip.Read(buffer, 0, buffer.Length);
        }

        using (FileStream fs = new FileStream(fPath, FileMode.OpenOrCreate, FileAccess.Write))
        {
            fs.Write(buffer, 0, buffer.Length);
        }

    }
}

【问题讨论】:

    标签: c# sharpziplib bzip2


    【解决方案1】:

    您正在使用using 语句。 using 语句是编译器指令,用于将 try finally 包裹在代码块周围,并在执行 finally 时调用 IDisposible.Dispose()。

    长话短说,在 BinaryWriter、BZip2InputStream 和 FileStream 上调用 dispose 可能会过早地处置父 MemoryStream。

    尝试从MemoryStream 中删除三个using 块,看看是否能解决您的问题。

    编辑

    您的BinaryWriter 正在向MemoryStream 写入一个byte。我不相信你需要一个 BinaryWriter 因为 MemoryStream 有一个 WriteByte() 方法。

    然后您的BZip2InputStream 正在尝试从MemoryStream 读取。但是MemoryStream 的位置位于流的末尾。没有要读取的数据,因此EndOfStreamException。

    【讨论】:

    • 刚试过这个,不幸的是,这似乎并没有真正解决问题,但我什至没有考虑过。感谢您的建议。
    • 您还在接收EndOfStreamException?哪条线路在做呢?
    • 是的,对不起。与之前创建 BZip2InputStream 时完全相同的行
    • 我相信我上次查看 SharpZipLib 时不再支持它。 IIRC 无论是打包还是拆包,它的性能都非常差。我见过的最流行的免费 .NET zip 库是DotNetZip。我不确定这是否是一种选择,但可能值得研究。
    • 哦,哇,是的,我现在明白你的意思了......非常棒的帮助,非常感谢!现在一切正常!
    【解决方案2】:

    OP 的代码有两个问题。 第一个,正如 Jason Whitted 所提到的,BinaryWriter 的 using 代码块导致 MemoryStream 实例的处置,因此我们应该删除该块,因为 MemoryStream 本身具有write 方法,这可以使用以下最干净的方式实现:

    var ms = new MemoryStream();
    ms.Write(inputBytes,0,inputBytes.Length); 
    

    第二个问题是当我们写入MemoryStream实例(ms)时,我们走到了它的末尾,所以在我们尝试使用BZip2InputStream之前我们必须把位置改回来到内存流的开头:

    ms.Seek(0, SeekOrigin.Begin); //THIS IS NECESSARY to change the position to the beginning
    byte[] buffer = null;
    using (var bz2InputStream = new BZip2InputStream(ms))
    {
           buffer = new byte[bz2InputStream.Length];
           bz2InputStream.Read(buffer, 0, buffer.Length);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多