I am trying to read file from the JarInputStream and the size of file is returning -1. I am accessing Jar file from the URL as a 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());
}
This is documented behavior. Javadoc says that getSize()
...
"Returns the uncompressed size of the entry data, or -1 if not known."
Obviously, this is a situation where the actual size of the uncompressed data is not known. Your application will just have to deal with this.
FOLLOWUP
You commented on another answer:
Though we have the total content size, i think with out having the individual file size we can't read the files.
If you don't have the size, you can still read the file and buffer it using a ByteArrayOutputStream
, then call toByteArray()
to extract the buffered bytes as a byte[]
. In fact, given that (per Tom Hawtin's comment) the reported size could be incorrect, you possibly should do this anyway, and just treat the reported size as a hint ... and just use it as the ByteArrayOutputStream
's initial capacity.
(Incidentally, the code in your question looks like it might have been intended to work that way ... judging from the 2nd to last line. The problem is that the rest of the code doesn't use the baos
object.)
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);
}
}
This might be because the server that's serving that url does not provide a contentLenght. this is similar to when you sometimes download a file with your browser and it says 33Kb/?? downloaded (as opposed to 33Kb/2049Kb downloaded).
To quickly check if that's the case you can do something like this:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With