1

我有一个奇怪的程序,其中 GzipInputStream 零填充缓冲区的一部分。我有幸知道字节在流中应该是什么样子,我可以看到缓冲区被 8 个正确字节和 12 个零(不应该为零)填充

字节应如下所示----> 0 20 82 22 -91 27 -96 65 66 65 88 32 32 32 32 81 32 0 0 0 100 78

字节实际上看起来像这样---> 0 20 82 22 -91 27 -96 65 66 65 0 0 0 0 0 0 0 0 0 0 0 0

前两个字节表示一个整数,它确定前两个之后的可变长度(以字节为单位)有效负载的大小。所以在这个例子中,第一个字节是 0 20,在 BIG_ENDIAN 中,这给了我们一个 20 字节的后续有效负载大小。

这是我的阅读代码

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);

所以前两个字节是有效负载数组中的字节,后 20 个字节是 messageBytes 中的字节。想不通

由于 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]);
            }
4

1 回答 1

5

约定read(byte[])是它读取一些数据,并返回已读取的字节数。就目前而言,您忽略了返回值。相反,您应该检查 的返回值read()并继续调用read(),直到您读取payloadSize字节。

一个简单的方法是read(b, off, len)在循环中使用:

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);
}
于 2013-01-17T20:10:12.993 回答