【问题标题】:How to read the ZipEntry CRC from a nested archive (zip in zip)如何从嵌套存档中读取 ZipEntry CRC(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。

标签: java zip


【解决方案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 检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多