【问题标题】:Inconsistency between ZipEntry size for ZipInputStream and JarInputStreamZipInputStream 和 JarInputStream 的 ZipEntry 大小不一致
【发布时间】:2023-03-13 00:27:01
【问题描述】:

我在一个 zip 文件中有一堆图像文件,我正在使用 ZipInputStream 读取这些图像文件,并从 Applet 中迭代 ZipEntry。

   ZipInputStream zis = new ZipInputStream(in);
        ZipEntry ze = null;
        while ((ze = zis.getNextEntry()) != null) {
            htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
            if (ze.isDirectory()) {
                continue;
            }
            int size = (int) ze.getSize();
            // -1 means unknown size.
            if (size == -1) {
                size = ((Integer) htSizes.get(ze.getName())).intValue();
            }
            byte[] b = new byte[(int) size];
            int rb = 0;
            int chunk = 0;
            while (((int) size - rb) > 0) {
                chunk = zis.read(b, rb, (int) size - rb);
                if (chunk == -1) {
                    break;
                }
                rb += chunk;
            }
            // add to internal resource hashtable
            htJarContents.put(ze.getName(), b);
        }

但是,当我将这些图像放入已签名的 jar 中时,“ze.getSize()”将变为 -1,并且图像文件读取不正确。

有人可以在这方面帮助我吗?

【问题讨论】:

标签: java jar applet zip signed-applet


【解决方案1】:

是的,-1 表示大小未知 - 不清楚为什么要将它放入地图然后再次取出它..

基本上,如果大小未知,您应该继续读取缓冲区,直到 read 返回 -1。一种简单的方法是创建一个ByteArrayOutputStream,并继续从ZipEntry 复制到该位置- 然后,一旦您完成阅读,只需从ByteArrayOutputStream 获取字节数组。它将处理任何必要的调整大小。

【讨论】:

    【解决方案2】:

    getSize() 返回条目数据的未压缩大小,如果未知,则返回 -1。

    所以如果返回的大小是负数,把它加到 0xffffffffl 得到正确的值。

    示例

    long size = ze.getSize();
    if (size < 0) {
        size = 0xffffffffl + size ;
    }
    

    参考Negative value returned for ZipEntry.getSize()

    【讨论】:

    • 请注意,OP 从 getSize 返回 -1,而不是由 int 溢出引起的大负数。您帖子中提到的错误也已在 java 6 update 18 中修复。
    【解决方案3】:

    这个问题和JarEntry.getSize() is returning -1 when the jar files is opened as InputStream from URL类似,答案是一样的。

    javadoc 明确指出,如果无法确定大小,该方法将返回 -1。而且(根据 Tom Hawtin 的说法)返回的大小也可能是非负数......并且不正确。

    最重要的是,您只需将报告的大小视为提示,并将整个流读入可扩展的字节缓冲区(例如 ByteArrayOutputStream)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-14
      • 2023-03-15
      • 1970-01-01
      • 2012-06-21
      • 2011-05-20
      • 1970-01-01
      • 2012-07-01
      • 1970-01-01
      相关资源
      最近更新 更多