libarchive 3.3.2读取7z归档部分条目失败,7z可正常提取
解决libarchive 3.3.2读取7z归档指定条目失败的问题
我之前在使用libarchive处理7z归档时也碰到过类似的坑,结合你描述的错误信息和场景,咱们一步步来排查解决:
先排查归档文件本身的问题
首先别上来就怀疑代码,先拿官方的7-Zip工具打开这些有问题的归档,看看能不能正常解压出file_1.fog和file.fog:
- 如果官方工具也报错,那说明这些归档本身就损坏了(比如传输丢包、存储损坏),和你的代码无关,需要重新获取完整的归档文件。
- 如果官方工具能正常解压,那问题就出在libarchive的版本或你的代码实现上。
针对libarchive 3.3.2的版本缺陷处理
libarchive 3.3.2是2019年的老版本,对7z格式的支持存在不少已知bug,尤其是对固实压缩、新LZMA2参数的7z归档兼容性很差。你看到的Decompressing internal error很大概率是这个原因:
- 优先尝试升级到libarchive最新稳定版(比如3.6.x及以上),后续版本修复了大量7z相关的解压和格式解析bug,很多这类问题升级后就能直接解决。
修复格式误识别的问题
你提到错误里有truncated RAR archive,这明显不对劲——你处理的是7z归档,却被识别成了RAR,这是老版本libarchive自动格式检测的bug。解决方法是强制指定解析格式为7z,不要依赖自动检测:
struct archive *a = archive_read_new(); // 先关闭自动格式检测,强制指定7z格式 archive_read_support_format_7zip(a); // 加上必要的过滤器支持 archive_read_support_filter_all(a); // 打开目标归档文件 int r = archive_read_open_filename(a, nam.c_str(), 10240); if (r != ARCHIVE_OK) { fprintf(stderr, "Open archive failed: %s\n", archive_error_string(a)); archive_read_free(a); return; }
检查代码的读取流程是否规范
你的list_archive函数要确保严格遵循libarchive的正确读取流程,尤其是处理固实压缩的7z归档时(固实压缩会把多个文件打包压缩,读取后面的条目需要先解压前面的内容):
- 必须循环调用
archive_read_next_header()遍历条目,直到找到目标文件,不能直接跳过前面的条目尝试读取(老版本libarchive不支持随机访问固实压缩的条目)。 - 每一步libarchive的调用都要检查返回值,比如
archive_read_next_header()、archive_read_data()的返回值,不要忽略错误。 - 读取完条目后,要确保调用
archive_read_data_skip()跳过未读取的内容,避免影响后续条目读取。 - 最后一定要调用
archive_read_free()释放资源,避免内存泄漏。
其他可能的排查点
- 如果归档是加密的,libarchive 3.3.2对加密7z的支持不完善,需要确保编译libarchive时启用了加密相关的依赖(比如libcrypto),或者升级到新版本处理加密归档。
- 检查你的代码中是否对文件名的大小写处理有误,7z归档的文件名是区分大小写的,确保你查找的文件名和归档内的完全一致。
内容的提问来源于stack exchange,提问作者Quang Hoang
相关产品推荐
相关产品推荐

