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

发布于 2024-12-05 08:07:25 字数 849 浏览 1 评论 0原文

我使用以下代码来解压缩 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨的味道风的声音 2024-12-12 08:07:25

作为一个猜想,我怀疑如果 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.

会傲 2024-12-12 08:07:25

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文