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.
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: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 useInputStreamthat reads resources directly from the file system, whereas when you run it from the jar file, you useInputStreamthat 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.