【问题标题】: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()

    长话短说,在 BinaryWriterBZip2InputStreamFileStream 上调用 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 所提到的,BinaryWriterusing 代码块导致 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
      相关资源
      最近更新 更多