当jar文件从URL打开为InputStream时,JarEntry.getSize()返回-1

Res*_*ddy 6 java jar inputstream

我试图从JarInputStream读取文件,文件的大小返回-1.我正在从URL访问Jar文件作为inputStream.

        URLConnection con = url.openConnection();

        JarInputStream jis = new JarInputStream(con.getInputStream());
        JarEntry je = null;

        while ((je = jis.getNextJarEntry()) != null) {
            htSizes.put(je.getName(), new Integer((int) je.getSize()));
            if (je.isDirectory()) {
                continue;
            }
            int size = (int) je.getSize();
            // -1 means unknown size.
            if (size == -1) {
                size = ((Integer) htSizes.get(je.getName())).intValue();
            }
            byte[] b = new byte[(int) size];
            int rb = 0;
            int chunk = 0;
            while (((int) size - rb) > 0) {
                chunk = jis.read(b, rb, (int) size - rb);
                if (chunk == -1) {
                    break;
                }
                rb += chunk;
            }
            // add to internal resource hashtable
            htJarContents.put(je.getName(), baos.toByteArray());
        }
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 4

这是有记录的行为。 JavadocgetSize()...

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

显然,这是一种不知道未压缩数据的实际大小的情况。您的应用程序只需要处理这个问题。


跟进

您评论了另一个答案:

尽管我们有总内容大小,但我认为如果没有单个文件大小,我们就无法读取文件。

如果您没有大小,您仍然可以读取文件并使用 a 对其进行缓冲ByteArrayOutputStream,然后调用toByteArray()以将缓冲字节提取为 a byte[]。事实上,鉴于(根据 Tom Hawtin 的评论)报告的大小可能不正确,您可能应该无论如何都这样做,并将报告的大小视为提示......并将其用作 的ByteArrayOutputStream初始容量。

(顺便说一句,你的问题中的代码看起来可能是这样工作的......从第二行到最后一行来看。问题是代码的其余部分不使用该baos对象。)