You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解压GZIP压缩数组前,如何获取原数组长度以申请适配缓冲区?

获取GZIP压缩字节数组的原始长度,精准适配缓冲区大小

嘿,我来帮你搞定这个问题!要在解压GZIP压缩字节数组前拿到原始数据的长度,其实不用费劲先解压——GZIP格式本身就在压缩数据的末尾藏了这个信息,咱们直接解析出来就行,这样就能精准申请适配大小的缓冲区了。

原理说明

GZIP格式的尾部有固定结构:最后4个字节是原始未压缩数据的长度(以32位无符号整数存储,采用小端字节序),再往前4个字节是CRC32校验值。我们只需要读取这最后4个字节,转换成整数就能得到原始数据的长度。

具体实现代码

先解析原始长度,再用这个长度初始化缓冲区和输出流,完整代码如下:

byte[] localByteBuf = ...; // 你的GZIP压缩字节数组
int originalLength = 0;

// 解析GZIP尾部的原始长度字段
if (localByteBuf.length >= 4) {
    // 小端字节序转整数:最后一个字节是最低位,依次左移拼接
    originalLength = ((localByteBuf[localByteBuf.length - 4] & 0xFF) << 24) |
                     ((localByteBuf[localByteBuf.length - 3] & 0xFF) << 16) |
                     ((localByteBuf[localByteBuf.length - 2] & 0xFF) << 8) |
                     (localByteBuf[localByteBuf.length - 1] & 0xFF);
}

// 用解析到的长度初始化缓冲区,兜底默认值1024(防止数据不完整的情况)
byte[] buffer = new byte[originalLength > 0 ? originalLength : 1024];
ByteArrayOutputStream out = new ByteArrayOutputStream(originalLength > 0 ? originalLength : 1024);

try (ByteArrayInputStream bin = new ByteArrayInputStream(localByteBuf);
     GZIPInputStream gis = new GZIPInputStream(bin)) {
    int len;
    while ((len = gis.read(buffer)) > 0) {
        out.write(buffer, 0, len);
    }
} catch (IOException e) {
    e.printStackTrace();
}

// 最终解压后的数据可以通过out.toByteArray()获取

注意事项

  • 局限性:如果原始数据长度超过4GB(2^32字节),32位的长度字段会溢出,无法正确获取长度。不过绝大多数业务场景都不会遇到这种极端情况。
  • 合法性校验:如果localByteBuf的长度小于4,说明这不是合法的GZIP数据或者数据不完整,这时候我们用默认的1024作为兜底,也可以根据业务需求抛出异常提示。

内容的提问来源于stack exchange,提问作者eahau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:31:48