Different behaviour with InputStream inside JAR

inputstream, java

Solution

`InputStream.read()` doesn't guarantee to fill the whole buffer at once, therefore you need to keep track of the number of bytes actually read:

byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = source.read(buffer)) != -1) {
    out.write(buffer, 0, bytesRead);
    loopCounter++;
} 

So, it's no surprise that number of bytes read per iteration may vary for different implementations of `InputStream`, and therefore the number of iterations may vary as well.

Actually, number of bytes read by specific call of `InputStream.read()` depends on many factors.

The first factor is implementation of `InputStream`: when you run your application from Eclipse, you use `InputStream` that reads resources directly from the file system, whereas when you run it from the jar file, you use `InputStream` that extracts resources form the jar file. Obviously, some internals of decompression algorithm for jar files may affect the size of chunks you get.

Another factor is behaviour of underlying environment. For example, system calls that read file from the file system may return chunks of different sizes as well, depending on some internal behaviour of the operating system, and so on.

Problem

I found myself to solve a strange bug in my software: the problem is that it manifested only when i package my application into a runnable JAR. The problem was in this simple code: i added loopCounter to count how many times the cycle is taken ``` private static byte[] read(InputStream source) { ByteArrayOutputStream out = new ByteArrayOutputStream(); int loopCounter = 0; int bytesRead; try { byte[] buffer = new byte[4096]; while ((bytesRead = source.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); loopCounter++; } } catch (IOException e) { e.printStackTrace(); } return out.toByteArray(); } ``` An example: ``` source = ClassLoader.class.getResourceAsStream("file.lol"); loopCounter in Eclipse = 1366 loopCounter in JAR = 1405 ``` My question is: why this significative difference for the same InputStream? EDIT : i change my code with the correct one, but the loopCounters are still different.

Original source