我真的被迫ReadToEnd()读取Ionic.Zlib.GZipStream的StreamReader吗?

时间:2011-09-18 14:45:26

标签: c# .net compression gzip streamreader

我使用以下代码解压缩GZipStream(使用DotNetZip library),其中fs是指向gz文件的文件流(使用FileMode.Open,FileAccess.Read,FileShare.ReadWrite):

using (var gz = new GZipStream(fs, CompressionMode.Decompress)) {
    using (var sr = new StreamReader(gz)) {
         header = sr.ReadLine();
    }
}

但是如果直到最后才读取文件(我不喜欢这样做,因为文件可能很大),它会抛出

ZlibException("Bad CRC32 in GZIP trailer. (actual(EC084966)!=expected(8FC3EF16))")

在第一个结束括号上(实际上是在试图关闭()StreamReader时。

现在如果在关闭流读取器之前调用ReadToEnd()(或者我使用while(!sr.EndOfStream)循环读取所有行),它就可以工作。 我观察到500 MB和200 kB压缩文件的行为相同,所以它似乎与文件大小无关。

非常欢迎您的见解!

这是a link to a simple dedicated test project

它适用于System.IO.GZipStream库,所以这很奇怪。

2 个答案:

答案 0 :(得分:4)

作为一个推测,我怀疑如果CRC块位于文件的末尾,那么如果我中止读取流,则在处理流时它无法验证完整性,因此会抛出异常。

然而,这并不能解释为什么它在使用System.IO.GzipStream时有效。

我找到了DotNetZip here源代码的相关部分,但似乎他们正在检查流是否被读到最后(参见// Make sure we have read to the end of the stream)。然后,他们会计算CRC32,因为异常消息显示一个。

答案 1 :(得分:0)

检查以确保您写入的驱动器没有空间不足。我有这个错误,它花了我一段时间,但我发现我真的没有空间了。