ZipInputStream和JarInputStream的ZipEntry大小之间的不一致

时间:2012-01-23 13:54:45

标签: java jar applet zip signed-applet

我在一个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,并且图像文件的读取错误。

在这方面,有人可以帮助我。

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:4)

getSize()返回条目数据的未压缩大小,或者在未知时返回-1。

因此,如果返回的大小为负数,请将其添加到0xffffffffl以获取正确的值。

示例

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

<强>参考Negative value returned for ZipEntry.getSize()

答案 2 :(得分:2)

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

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

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