GZIPInputStream.read()读取字节数小于指定长度的原因排查
GZIPInputStream.read()返回值小于指定长度的场景及解决方法
返回值小于指定长度的常见场景
- 压缩块边界限制:GZIP是按块压缩的,每个压缩块解压后有固定长度。当你请求的字节数跨越两个压缩块时,当前
read()调用只能返回当前块解压后的剩余字节,剩下的得在下一次调用里获取。JDK官方文档没明确提这个分块逻辑,但这是GZIP底层压缩机制的固有特性。 - 流接近末尾:当流里剩下的未解压数据不足你指定的
len长度时,read()会返回剩余的字节数,最后一次调用会返回-1表示流结束。 - 底层输入流限制:如果GZIPInputStream包装的底层流(比如
FileInputStream)自身read()返回的字节数比预期少,也会导致GZIPInputStream的read()返回更少字节——因为它得先从底层流读压缩数据,再解压。
实现类似readFully的读取逻辑
要是你需要确保每次读到指定长度的字节(直到流结束),可以自己封装一个工具方法,循环调用read()直到填满缓冲区或者流结束:
public static void readFully(GZIPInputStream in, byte[] buf, int off, int len) throws IOException { int totalRead = 0; while (totalRead < len) { int bytesRead = in.read(buf, off + totalRead, len - totalRead); if (bytesRead == -1) { throw new EOFException("Unexpected end of GZIP stream"); } totalRead += bytesRead; } }
调用这个方法就能像RandomAccessFile.readFully()那样,要么填满指定长度的缓冲区,要么在流提前结束时抛出EOFException。
内容的提问来源于stack exchange,提问作者Sriman S
相关产品推荐
相关产品推荐

