如何从嵌套存档中读取 ZipEntry CRC(zip in zip)
Posted
技术标签:
【中文标题】如何从嵌套存档中读取 ZipEntry CRC(zip in zip)【英文标题】:How to read the ZipEntry CRC from a nested archive (zip in zip) 【发布时间】:2013-10-15 23:35:38 【问题描述】:查看所选答案的 cmets,问题出在我的测试数据上,而不是代码上。
我正在尝试使用 ZipEntry 对象读取 Zip 存档的 CRC。这适用于直接在文件系统上的 zip。
zStream = new ZipInputStream(new FileInputStream(zipPath))
zEntry = zStream.getNextEntry()
zEntry.getCrc()
我想从嵌套的 zipEntry 中获取 CRC,但我总是返回 -1
zStream = new ZipInputStream(new ZipFile(zipPath).getInputStream(zEntry))
zStream.getNextEntry().getCrc()
// always equal -1
有没有办法在不将嵌套 zip 提取到 FS 的情况下读取 CRC?为什么它不能按原样工作?
【问题讨论】:
您在第二个示例中使用的是哪个zEntry
?
@SotiriosDelimanolis 嵌套 zip 的 zEntry
也许我今天很慢,但我想看看您尝试从中提取的 zip 结构以及您尝试读取的 CRC。
【参考方案1】:
zStream = new ZipInputStream(new ZipFile(zipPath).getInputStream(zEntry))
那行不通。试试这个:
ZipInputStream innerZip = new ZipInputStream(zStream);
在你找到相关的(外部)ZEntry
之后,迭代innerZip
自己的 ZEntries 并获取他们的 CRC 等,无论你想要什么。
【讨论】:
嵌套的 CRC 仍然返回 -1,而且关闭内部流也会影响外部流。 所以不要关闭它。也许嵌套条目上没有 CRC? 我得出了同样的结论。我查看了嵌套条目(一个签名的 jar),似乎 jarsigner 正在从存档中删除 CRC。【参考方案2】:如果一个接一个地读取条目,java.util.zip.ZipInputStream 的实现不会传递当前条目的CRC。仅在再次调用 getNextEntry() 后才可用(对于上一个条目)!
AFAIK 这没有记录,但迫切需要。
【讨论】:
【参考方案3】:这看起来确实是 ZipEntry 界面的错误/限制。应该有一个 API 来计算 CRC。
这里有一些 Groovy 代码来生成缺失的 CRC:
long calculateCRC( zStream)
def crc32 = new CRC32()
crc32.update( IOUtils.toByteArray(zStream))
return crc32.value
【讨论】:
为什么?除非 zip 文件中有 CRC 可以与之比较,否则这是没有意义的。不是错误。不是限制。 因此您同意 ZipEntry CRC 没有用,除非您手动生成 CRC。我仍然认为 Java Zip API 应该提供这个功能,而不是强迫每个人都在那里滚动自己的 CRC 检查。以上是关于如何从嵌套存档中读取 ZipEntry CRC(zip in zip)的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用临时文件的情况下从 Java 中的嵌套 zip 文件中读取数据?