minizip内存解压必须用mz_zip_reader_init_mem传完整zip二进制数据,禁用init_file;遍历用索引+get_filename;解压单文件用extract_file_to_mem;须显式调用mz_zip_reader_end释放资源,且不可跨线程共享实例。

minizip 读取内存中 ZIP 数据必须用 mz_zip_reader_init_mem
直接传指针给 mz_zip_reader_init_file 会崩溃——它只认磁盘路径。内存解压的入口函数就一个:mz_zip_reader_init_mem,且要求数据完整、不可被释放或移动。
常见错误现象:mz_zip_reader_init_mem 返回 0(失败),但没检查 errno 或调用 mz_zip_get_last_error;或者传入的 buffer 指针在 zip 对象生命周期内被 free 或越界写入。
- buffer 必须是完整 ZIP 文件的原始二进制内容(含 EOCD、central directory 等),不能是截断或拼接过的
- size 参数是
size_t类型,别用int强转,32 位系统下大 ZIP(>2GB)易出错 - 第 4 个参数
flags建议设为0;设MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY可能导致遍历顺序异常
遍历内存 ZIP 内文件名要用 mz_zip_reader_get_filename + 循环索引
不能靠 std::string 拼路径或硬编码文件名——ZIP 中文件名是动态的,且可能含 Unicode(需 UTF-8 编码)、斜杠、点号等特殊字符。正确方式是先用 mz_zip_reader_get_num_files 拿总数,再按索引逐个查。
使用场景:加载资源包里的 config.json 或 texture.png,但你不确定它在 ZIP 里的确切路径层级。
- 索引从
0开始,上限为mz_zip_reader_get_num_files(z) - 1,越界访问会触发断言或 segfault -
mz_zip_reader_get_filename(z, i)返回的是内部 const char*,别保存指针长期使用;需拷贝用std::string或strdup - 文件名不含前导
/,但可能有assets/这样的目录前缀;注意区分大小写(ZIP 标准不强制大小写敏感,但 minizip 默认区分)
解压单个内存文件到缓冲区用 mz_zip_reader_extract_file_to_mem 最稳
别手写 inflate 循环或调 mz_zip_reader_extract_to_file 再读回内存——多一次磁盘 I/O,还引入临时文件和权限问题。直接进内存,一气呵成。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
性能影响:该函数内部已做 chunked 解压和 buffer 复用,比手动分块调 mz_zip_reader_extract_file_to_callback 更少出错,也更快。
- 目标 buffer 需提前 malloc,大小必须 ≥
mz_zip_reader_get_file_info返回的uncompressed_size;小了会截断,大了没事 - 返回值是
size_t实际解压字节数,不是 bool;等于 0 表示失败(比如 CRC 错、内存不足) - 如果文件本身是加密 ZIP(ZipCrypto 或 AES),
mz_zip_reader_extract_file_to_mem默认不支持,会静默失败——得换minizip-ng或自己 hook 密码回调
minizip 内存解压后必须显式调 mz_zip_reader_end
不调这个,zip 对象占用的内存(包括内部 malloc 的 central directory 缓存)不会释放,且后续无法安全复用同一对象。这不是 RAII 类库,没有析构自动清理。
容易踩的坑:在函数里局部声明 mz_zip_archive,以为作用域结束就自动释放;实际只是栈上结构体消失,堆内存全 leaked。
- 必须在所有
mz_zip_reader_*调用之后、且确认不再访问该 zip 对象时,立即调mz_zip_reader_end(&z) - 如果解压多个文件,别在每次提取后都
end再init_mem——重复 init/end 开销大;应 init 一次,提取多次,最后 end 一次 -
mz_zip_reader_end内部会 free 所有它 malloc 的内存,但不会 touch 你传进去的原始 buffer(即 init_mem 时那个指针),那部分仍由你管理
最常被忽略的点:跨线程共享同一个 mz_zip_archive 实例。minizip 不是线程安全的——即使只读,多个线程同时调 mz_zip_reader_get_filename 也可能因内部状态冲突而返回错乱字符串或崩溃。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










