JarEntry.getSize () returns -1 when jar files open as InputStream from a URL

I am trying to read a file from a JarInputStream and the file size is returned -1. I am accessing the Jar file from the URL as 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());
        }
+5
source share
3 answers

This is documented behavior. Javadoc says that getSize()...

"Returns the uncompressed size of the record data, or -1 if not known."

Obviously, this is a situation where the actual size of the uncompressed data is unknown. Your application will simply deal with this.


Followup

You commented on another answer:

Although we have a common content size, I think that without a separate file size, we cannot read files.

, ByteArrayOutputStream, toByteArray(), byte[]. , , ( Tom Hawtin) , , , , ... ByteArrayOutputStream.

(, , ... 2- . , baos .)

+3
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);
    }
}
+3

Perhaps this is because the server serving this URL does not provide contentLenght. this is similar to when you sometimes download a file using your browser and it says 33Kb / ?? loaded (unlike 33Kb / 2049Kb).

To quickly check if you can do something like this in this case:

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);
}
+1
source

All Articles