如何实现与Unzlib_bin对应的压缩函数,还原原始*.bin文件?
修正Zlib_bin压缩函数以匹配Unzlib_bin的格式
先拆解你的Unzlib_bin解压逻辑,明确原始*.bin文件的结构,这样我们就能精准对齐压缩后的格式:
原始*.bin的结构是:
- 前8字节:自定义头部数据
- 偏移8-11:4字节整数 → 压缩后的数据长度
- 偏移12-15:4字节整数 → 原始未压缩数据长度
- 偏移16开始:zlib压缩后的核心数据
你的压缩函数主要存在3个问题,下面是修正后的完整代码和细节说明:
public void Zlib_bin(byte[] data, string target_location) { // 1. 初始化zlib压缩器,直接在构造时设置最优压缩级别 var deflater = new Deflater(Deflater.BEST_COMPRESSION); deflater.SetInput(data, 0, data.Length); deflater.Finish(); // 2. 动态收集压缩数据(避免固定长度缓冲区导致的截断问题) var compressedBytes = new List<byte>(); var tempBuffer = new byte[4096]; // 用4KB缓冲区分批读取压缩结果 while (!deflater.IsFinished) { int bytesWritten = deflater.Deflate(tempBuffer); if (bytesWritten > 0) { compressedBytes.AddRange(tempBuffer.Take(bytesWritten)); } } // 3. 按原始bin格式拼接最终数据 var finalBinData = new List<byte>(); // 替换成你实际的自定义8字节头部(比如原bin文件的前8字节) finalBinData.AddRange(new byte[8]); // 添加压缩后的数据长度(对应解压时的BitConverter.ToInt32(data, 8)) finalBinData.AddRange(BitConverter.GetBytes(compressedBytes.Count)); // 添加原始未压缩数据长度(对应解压时的BitConverter.ToInt32(data, 12)) finalBinData.AddRange(BitConverter.GetBytes(data.Length)); // 添加实际的zlib压缩数据 finalBinData.AddRange(compressedBytes); // 4. 写入目标文件 File.WriteAllBytes(target_location, finalBinData.ToArray()); // 释放zlib资源 deflater.End(); }
关键修正点说明:
- 动态收集压缩数据:zlib压缩后的长度无法提前确定,用循环+临时缓冲区的方式,确保获取全部压缩结果,避免原代码中固定长度缓冲区导致的数据丢失
- 移除冗余参数:原函数中的
int length完全多余,压缩后的长度由compressedBytes.Count动态获取 - 严格匹配头部顺序:按照「自定义头部→压缩长度→原始长度→压缩数据」的顺序拼接,和解压函数的读取逻辑完全对应
- 资源清理:调用
deflater.End()释放zlib相关资源,避免内存泄漏
额外注意事项:
- 务必把代码中
new byte[8]替换成你实际的自定义头部数据(比如从原始bin文件读取的前8字节) - 注意字节序问题:
BitConverter的字节序依赖系统,如果原始bin使用大端字节序,需要手动反转字节数组(可通过BitConverter.IsLittleEndian判断后处理)
内容的提问来源于stack exchange,提问作者Vlad i Slav
相关产品推荐
相关产品推荐

