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

zlib压缩数据位置获取及重启后解压缩恢复问题咨询

问题分析与解决方案

1. 修正inflatePrime()的参数理解与传递

inflatePrime()的原型为:

int inflatePrime(z_streamp strm, int bits, int value);
  • 第一个参数必须传入初始化后的z_stream指针,你当前的调用缺少这个核心参数。
  • 第二个参数bits是需要向解压缩器注入的未处理位的数量(范围0-7),而非位偏移值。
  • 第三个参数value是包含这些未处理位的字节,且未处理位位于该字节的高位(例如剩余3位,则取字节的高3位)。

你当前收集streamBits的方式有误:stream.data_type的低3位才是剩余未处理的位数量(0-7),正确提取逻辑应为:

int remaining_bits = stream.data_type & 0x7; // 取低3位,范围0-7

剩余位对应的字节值需要从stream->next_in的前一个字节获取(因为next_in已指向下一个待处理字节),保存时需额外记录该字节值,而非直接从data_type提取。

2. 修正压缩数据位置的恢复逻辑

unzGetCurrentFileZStreamPos64()返回的是压缩数据的字节偏移量,恢复时需先定位到该偏移,再注入剩余位:

  • 重启后打开目标zip文件,定位到对应文件条目,调用unzSetOffset64()将压缩数据流指针移动到保存的streamCurrentPos位置。
  • 初始化z_stream结构(需与最初解压缩时的参数完全一致,如窗口大小、解压缩模式等),调用inflateInit2()完成初始化。

3. 完整恢复流程示例

// 1. 打开zip文件并定位到目标条目
unzFile uf = unzOpen("your_file.zip");
unzLocateFile(uf, "target_file.txt", 0);
unzSetOffset64(uf, saved_state.streamCurrentPos);

// 2. 初始化z_stream(参数需与原流程一致)
z_stream strm = {0};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
// windowBits参数必须和原解压缩初始化时完全匹配
inflateInit2(&strm, 15 + 32); 

// 3. 恢复字典
inflateSetDictionary(&strm, saved_state.dictionary_buf, saved_state.dictLength);

// 4. 注入剩余未处理位
inflatePrime(&strm, saved_state.remaining_bits, saved_state.remaining_byte);

// 5. 继续解压缩流程
Byte out_buf[4096];
int ret = unzReadCurrentFile(uf, out_buf, sizeof(out_buf));

4. 排查Z_STREAM_END异常的原因

出现Z_STREAM_END通常是以下问题导致:

  • 字节偏移定位错误:unzSetOffset64()未正确指向保存的压缩数据位置,导致解压缩器直接读到流末尾。
  • inflatePrime()参数错误:注入的位数量或字节值不正确,导致解压缩器误判流结束。
  • 初始化参数不匹配:重启时inflateInit2()的windowBits等参数与原流程不一致,导致状态不兼容。

5. 补充完善状态保存结构体

你的state_of_uncompression需要补充剩余位对应的字节值字段:

typedef struct state_of_uncompression
{
  uint64_t streamCurrentPos;  // 压缩数据的字节偏移(来自unzGetCurrentFileZStreamPos64())
  int remaining_bits;         // 剩余未处理的位数量(0-7)
  Byte remaining_byte;        // 包含剩余位的字节值(从stream->next_in[-1]获取)
  Byte dictionary_buf[32768]; // 字典数据(来自inflateGetDictionary())
  uInt dictLength;            // 字典长度(来自inflateGetDictionary())
  uint64_t output_wrt_offset; // 输出偏移量
} uncompression_state_info;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:50:31