我真的被迫 ReadToEnd() StreamReader 读取 Ionic.Zlib.GZipStream 吗?
我使用以下代码来解压缩 GZipStream(使用 DotNetZip 库),其中 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))")
在第一个右括号上(实际上是在尝试 Close() StreamReader 时。
现在如果调用 ReadToEnd () 在关闭流读取器之前(或者我使用 while(!sr.EndOfStream) 循环读取所有行),它可以工作。 我在 500 MB 和 200 kB 压缩文件中观察到相同的行为,因此它似乎与文件大小无关。
非常欢迎您的见解!
它与 System.IO.GZipStream 库一起工作,所以这很奇怪。
I am using the following code to uncompress a GZipStream (using DotNetZip library), where fs is a filestream pointing to a gz file (with FileMode.Open, FileAccess.Read, FileShare.ReadWrite):
using (var gz = new GZipStream(fs, CompressionMode.Decompress)) {
using (var sr = new StreamReader(gz)) {
header = sr.ReadLine();
}
}
But if the file is not read till the end (which I prefer to do when not needed as the file can be huge), it throws
ZlibException("Bad CRC32 in GZIP trailer. (actual(EC084966)!=expected(8FC3EF16))")
on the first closing bracket (actually when trying to Close() the StreamReader.
Now if call ReadToEnd() before closing the streamreader (or I read all lines using a while(!sr.EndOfStream) loop), it works.
I have observed the same behaviour with a 500 MB and 200 kB compressed file, so it seems it is not related to the file size.
Your insight is very welcome!
Here is a link to a simple dedicated test project.
It works with the System.IO.GZipStream library, so this is very strange.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
作为一个猜想,我怀疑如果 CRC 块位于文件末尾,那么如果我中止读取流,它在处理流时无法验证完整性,因此会引发异常。
然而,这并不能解释为什么它在使用 System.IO.GzipStream 时有效。
我在 here 找到了 DotNetZip 源代码的相关部分,但是它似乎他们正在检查流是否已读取到末尾(请参阅
//确保我们已读取到流的末尾
)。然后,他们计算 CRC32,如异常消息所示。As a conjecture, I suspect that if the CRC block is at the end of the file, then if I abort reading the stream, it cannot have verified the integrity while disposing the stream and therefore throws the exception.
However this would not explain why it works when using
System.IO.GzipStream
.I found the relevant part of the source code of DotNetZip here, but it seems they are checking that the stream is read to the end (see
// Make sure we have read to the end of the stream
). Then, they do compute a CRC32 as the exception message shows one.检查并确保您要写入的驱动器没有空间不足。我遇到了这个错误,花了我一段时间,但我发现我真的没有空间了。
Check to make sure the drive you're writing to is not out of space. I had this error and it took me awhile but I figured out I was really out of space.