Reputation: 219
I have bunch of image files in a zip file which I am reading using ZipInputStream and Iterating over ZipEntry from an Applet.
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);
}
However when I put these images into a signed jar "ze.getSize()
" is coming as -1, and image file is getting read incorrectly.
Can someone help me in this regards.
Upvotes: 5
Views: 8440
Reputation: 585
getSize() returns the uncompressed size of the entry’s data, or -1 when not known.
So if the size returned is negative, add it to 0xffffffffl to get the correct value.
Example:
long size = ze.getSize();
if (size < 0) {
size = 0xffffffffl + size ;
}
Reference: Negative value returned for ZipEntry.getSize()
Upvotes: 2
Reputation: 718886
This question is similar to JarEntry.getSize() is returning -1 when the jar files is opened as InputStream from URL and the answer is the same.
The javadoc specifically states that that method returns -1
if the size cannot be determined. And (according to Tom Hawtin) it is also possible that the size returned is non-negative ... and incorrect.
The bottom line is that you need to treat the reported size as a hint only, and read the entire stream into and expandable byte buffer (e.g. a ByteArrayOutputStream).
Upvotes: 2
Reputation: 1500825
Yes, -1 means the size is unknown - it's not clear why you're putting it into a map and then fetching it out again though..
Basically, if the size is unknown you should keep reading buffers until read
returns -1. One simply way is to create a ByteArrayOutputStream
, and keep copying from the ZipEntry
to that - then once you've finished reading, just get the byte array from the ByteArrayOutputStream
. It will handle any resizing necessary.
Upvotes: 5