使用LibZip打开Zip文件遇异常:zip_stat返回-1且文件大小为0
问题分析与解决方案
你遇到的问题核心是对LibZip API的使用逻辑理解有误,我来帮你拆解并修正:
1. 核心错误:zip_stat的参数误用
zip_open打开的是你本地的file.zip归档文件,但zip_stat的第二个参数需要传入的是归档内部的具体文件名,而不是归档本身的名称。你现在传入"file.zip",相当于在归档里找一个叫file.zip的文件,显然不存在,所以zip_stat返回-1,st.size自然为0。
2. 修正后的代码示例
假设你的归档里有一个叫inner_file.txt的文件,修正后的代码应该是这样的:
#include <iostream> #include <zip.h> int main() { int err = 0; // 打开本地的zip归档文件 zip_t *z = zip_open("file.zip", 0, &err); if (!z) { std::cerr << "打开归档失败,错误码:" << err << std::endl; return 1; } zip_stat_t st; zip_stat_init(&st); // 传入归档内部的文件名,比如inner_file.txt int stat_result = zip_stat(z, "inner_file.txt", 0, &st); if (stat_result == -1) { // 获取zip_stat的错误信息 zip_error_t error; zip_error_init_with_code(&error, zip_get_error(z)->code); std::cerr << "获取文件状态失败:" << zip_error_strerror(&error) << std::endl; zip_error_fini(&error); zip_close(z); return 1; } std::cout << "文件大小:" << st.size << std::endl; // 读取文件内容的代码现在可以正常测试了 char *contents = new char[st.size]; zip_file *f = zip_fopen(z, "inner_file.txt", 0); if (f) { zip_fread(f, contents, st.size); // 这里可以处理读取到的内容,比如输出 std::cout << "文件内容:" << contents << std::endl; zip_fclose(f); } delete[] contents; zip_close(z); return 0; }
3. 额外技巧:遍历归档内的所有文件
如果你不确定归档里有哪些文件,可以用下面的代码遍历所有条目:
int num_entries = zip_get_num_entries(z, 0); for (int i = 0; i < num_entries; ++i) { const char *name = zip_get_name(z, i, 0); std::cout << "归档内文件:" << name << std::endl; }
4. 关于错误码的说明
你提到err始终为0,这是因为zip_open的err参数只负责记录打开归档阶段的错误,而zip_stat、zip_fopen等操作的错误需要通过zip_get_error来获取,就像上面代码里的处理方式,这样才能拿到具体的错误原因。
内容的提问来源于stack exchange,提问作者user10134426
相关产品推荐
相关产品推荐

