System.Zip.TZipFile.ExtractZipFile 对某些文件抛出错误。为啥?

Posted

技术标签:

【中文标题】System.Zip.TZipFile.ExtractZipFile 对某些文件抛出错误。为啥?【英文标题】:System.Zip.TZipFile.ExtractZipFile throws error with certain files. Why?System.Zip.TZipFile.ExtractZipFile 对某些文件抛出错误。为什么? 【发布时间】:2015-12-08 00:15:55 【问题描述】:

使用System.Zip.TZipFile解压ZIP文件时:

System.Zip.TZipFile.ExtractZipFile('C:\test.zip', 'R:\_TEST\');

对于特定的 ZIP 文件,我收到此错误消息框:

流读取错误。

为什么?

重现错误的 zip 文件,base64 编码:

UEsDBC0ACAAIAHyDiEcAAAAA ////////// 8WABQATmV1ZXMgVGV4dGRva3VtZW50LnR4dAEAEAAA AAAAAAAAAAIAAAAAAAAAAwBQSwcIAAAAAAIAAAAAAAAAAAAAAAAAAABQSwECLQstAAgACAB8g4hH AAAAAP ////////// FgA4AAAAAAABAAAAAAAAAAAATmV1ZXMgVGV4dGRva3VtZW50LnR4dAEAEAAA AAAAAAAAAAIAAAAAAAAACgAgAAAAAAABABgA1LFkAs0x0QHUsWQCzTHRAdSxZALNMdEBUEsFBgAA AAABAAEAfAAAAGIAAAAAAA == P>

转到http://www.motobit.com/util/base64-decoder-encoder.asp

将此解码到本地存储为 test.zip(不要更改字符集)

解码后的二进制文件的MD5必须是:

7357193E8F27FE1FB5AF2B8B6AF1F24C

【问题讨论】:

@DavidHeffernan 我提供了一个允许重现错误的示例。 @DavidHeffernan 你能重现错误吗? 【参考方案1】:

参考:The structure of a PKZip file by Florian Buchholz.

您的 ZIP 文件使用该格式的 ZIP64 扩展变体存储。 Delphi 邮政编码不支持 ZIP64。

我通过查看本地文件头推断该文件是 ZIP64。压缩和未压缩的大小字段都是0xffffffff。从上面的参考:

压缩后的大小:如果压缩包是ZIP64格式,这个字段是0xffffffff,长度存储在额外字段中 未压缩大小:如果压缩包为ZIP64格式,则该字段为0xffffffff,长度存储在额外字段中

对于支持 ZIP64 的库,它需要检测这些条件并从附加标头中读取 64 位值。 Delphi 代码不尝试读取不存在的0xffffffff 字节。

您需要找到一个不同的 ZIP 文件库,一个支持 ZIP64 的库,才能对此类 ZIP 文件进行操作。或者,如果您可以安排创建 ZIP 文件的任何内容都使用纯 ZIP 格式,您可以回避这个问题。

【讨论】:

有趣的是,System.Zip.TZipFile.IsValid 为同一个 ZIP 文件返回 TRUE,这会在提取时产生错误。这是不一致的。 我没有看到不一致的地方。这只是一种不受支持的格式。 换句话说,库不能告诉你它是无效的,因为它是在完全不了解 ZIP64 的情况下编写的。我认为添加 ZIP64 支持非常容易。但如果我是你,我会改用 abbrevia。 我现在测试了 Abbrevia,它工作得很好(当然,即使是上面的 ZIP 文件)。 - 那么为什么 Embarcadero 不向 System.Zip 添加 ZIP64 支持,也许在你的帮助下? 我不知道。我猜这只是另一件事。也许您可以向质量门户提交问题。无论如何,我认为这一切现在都完成了,对吧?

以上是关于System.Zip.TZipFile.ExtractZipFile 对某些文件抛出错误。为啥?的主要内容,如果未能解决你的问题,请参考以下文章