Question

I am having a strange program with a GzipInputStream zero filling part of the buffer. I have the fortune of knowing what the bytes are supposed to look like in the stream and I can see the buffer is being filled with 8 correct bytes and 12 zeros (shouldn't be zero)

BYTES SHOULD LOOK LIKE THIS----> 0 20 82 22 -91 27 -96 65 66 65 88 32 32 32 32 81 32 0 0 0 100 78

BYTES ACTUALLY LOOK LIKE THIS---> 0 20 82 22 -91 27 -96 65 66 65 0 0 0 0 0 0 0 0 0 0 0 0

The first two bytes represent an integer that determine the size of the variable length (in bytes) payload after the first two. So in this example, the first bytes are 0 20 and in BIG_ENDIAN this gives us a subsequent payload size of 20 bytes.

Here is my code for reading

gzipInputStream = new GZIPInputStream(url.openStream());        

byte[] payload = new byte[2];
gzipInputStream.read(payload);
for(int i=0;i<payload.length;i++){
    System.out.println(payload[i]);
}
int payloadSize = ((payload[0] & 0xFF) << 8) | ((payload[1]) & 0xFF);
//read the next payloadSize bytes
byte[] messageBytes = new byte[payloadSize];

gzipInputStream.read(messageBytes);

So the first two bytes are those in the payload array and the second 20 bytes are those in messageBytes. Can't figure it out

Modified code thanks to NPE

            byte[] payloadSizeBytes = new byte[2];
            int payloadSizeBytesRead = 0;
            while(payloadSizeBytesRead < 2){
                int r = gzipInputStream.read(buffer);
                if(r>0){
                    payloadSizeBytes[payloadSizeBytesRead] = buffer[0];
                    payloadSizeBytesRead++;
                }
            }
            int payloadSize = ((payloadSizeBytes[0] & 0xFF) << 8) | ((payloadSizeBytes[1]) & 0xFF);
            //read the next payloadSize bytes
            byte[] messageBytes = new byte[payloadSize];
            int messageBytesRead = 0;
            while(messageBytesRead < payloadSize){
                int r = gzipInputStream.read(buffer);
                if(r>0){
                    messageBytes[messageBytesRead] = buffer[0];
                    messageBytesRead++;
                }
            }
            for(int i=0;i<messageBytes.length;i++){
                System.out.println(messageBytes[i]);
            }
Was it helpful?

Solution

The contract on read(byte[]) is that it reads some data, and returns how many bytes have been read. As things stand, you are ignoring the return value. Instead, you should examine the return value of read() and keep calling read() until you've read payloadSize bytes.

An easy way to do this is by using read(b, off, len) in a loop:

int payloadSize = ((payload[0] & 0xFF) << 8) | ((payload[1]) & 0xFF);
byte[] messageBytes = new byte[payloadSize];

int bytesRead = 0;
while (bytesRead < payloadSize) {
   bytesRead += gzipInputStream.read(messageBytes, bytesRead, payloadSize - bytesRead);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top