我正在尝试从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());
}
答案 0 :(得分:4)
这是记录在案的行为。 Javadoc说getSize()
...
“返回条目数据的未压缩大小,如果不知道则返回-1。”
显然,这是未知压缩数据的实际大小的情况。您的申请只需处理此问题。
<强>后续强>
您评论了另一个答案:
虽然我们有总内容大小,但我认为没有单独的文件大小我们无法读取文件。
如果没有大小,您仍然可以使用ByteArrayOutputStream
读取文件并对其进行缓冲,然后调用toByteArray()
将缓冲的字节提取为byte[]
。事实上,鉴于(根据Tom Hawtin的评论),报告的大小可能不正确,无论如何你可能应该这样做,并且只是将报告的大小视为提示......并且只是将其用作ByteArrayOutputStream
的初始容量。
(顺便说一下,你问题中的代码看起来可能是以这种方式工作......从第2行到最后一行判断。问题是代码的其余部分没有使用{{1对象。)
答案 1 :(得分:4)
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);
}
}
答案 2 :(得分:1)
这可能是因为服务该网址的服务器未提供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);
}