5

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

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

4

3 回答 3

4

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

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

于 2012-01-23T13:59:09.000 回答
3

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

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

示例

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

参考为 ZipEntry.getSize() 返回负值

于 2013-08-03T03:57:07.577 回答
2

这个问题类似于JarEntry.getSize() 在从 URL 作为 InputStream 打开 jar 文件时返回 -1并且答案是相同的。

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

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

于 2012-01-23T14:03:57.303 回答