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

我试图从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()); } 

这是记录在案的行为。 Javadoc说getSize() ……

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

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


跟进

您评论了另一个答案:

虽然我们有总内容大小,但我认为没有单独的文件大小我们无法读取文件。

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

(顺便说一下,你的问题中的代码看起来可能是以这种方式工作……从第2行到最后一行判断。问题是代码的其余部分不使用baos对象。)

 byte[] classbytes = null; JarInputStream jis = new JarInputStream(is); JarEntry je = null; String jename = null; while((je = jis.getNextJarEntry()) != null){ jename = je.getName(); if(je.getSize() != -1){ classbytes = new byte[(int)je.getSize()]; int len = (int) je.getSize(); int offset = 0; while (offset != len) offset += jis.read(classbytes, offset, len - offset); classes.put(jename, classbytes); } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(); while(true){ int qwe = jis.read(); if(qwe == -1) break; baos.write(qwe); } classbytes = baos.toByteArray(); classes.put(jename, classbytes); } } 

这可能是因为服务该URL的服务器不提供contentLenght。 这类似于你有时用浏览器下载文件,它说33Kb / ?? 下载(相对于33Kb / 2049Kb下载)。

要快速检查是否是这种情况,您可以执行以下操作:

 URL url = new URL(yourUrl); conn = url.openConnection(); size = conn.getContentLength(); if(size < 0) { System.out.println("Could not determine file size."); } else { System.out.println(yourUrl + "\nSize: " + size); }