功能实现需要依赖相关头文件和库文件,我这里的是64位的。需要的可以在这下载:https://download.csdn.net/download/bangtanhui/88403596
参考代码如下:
#include
#include
#include
#include
#pragma comment(lib,"libzip.lib")
//解压压缩包
//传参:压缩包路径、目标文件夹路径
void DriverList::unZip(const char* zipName, const char* dirName) {
int iErr = 0;
struct zip* zipfile = NULL;
struct zip_file* entries = NULL;
struct zip_stat stat;
zip_int64_t i64Num = 0;
zip_int64_t i64Count = 0;
int iRead = 0;
int iLen = 0;
char buf[1024];
memset(&stat, 0, sizeof(stat));
memset(buf, 0, sizeof(buf));
zipfile = zip_open(zipName, ZIP_CHECKCONS, &iErr);
if (!zipfile)
{
printf("zip open failed:%d\n", iErr);
exit(EXIT_FAILURE);
}
//get how many entrrites in archive
i64Num = zip_get_num_entries(zipfile, 0);
for (i64Count = 0; i64Count < i64Num; i64Count++)
{
iLen = 0;
if (zip_stat_index(zipfile, i64Count, 0, &stat) == 0)
{
printf("the file name is:%s\n", stat.name);
}
entries = zip_fopen_index(zipfile, i64Count, 0);
if (!entries)
{
printf("fopen index failed\n");
goto End;
}
//create the original file
char filePath[MAX_PATH]{ 0 };
strcpy(filePath, dirName);
strcat(filePath, "/");
strcat(filePath, stat.name);
FILE* fp = fopen(filePath, "wb+");
if (!fp)
{
printf("create local file failed\n");
goto End;
}
while (iLen < stat.size)
{
iRead = zip_fread(entries, buf, 1024);
if (iRead < 0)
{
printf("read file failed\n");
fclose(fp);
goto End;
}
fwrite(buf, 1, iRead, fp);
iLen += iRead;
}
fclose(fp);
}
End:
zip_close(zipfile);
}
工程的“包含目录”和“库目录”需要包含相关路径
程序运行可能还需要依赖当前exe路径下相关dll文件
后续发现上面代码的方法,遇到压缩包中有文件夹的,会解压失败。
可以尝试下面这种方法,亲测可行:
#include
#include
#include
#include
#pragma comment(lib,"libzip.lib")
void extractArchive(const char* archivePath, const char* outputPath) {
// 打开压缩包
zip* archive = zip_open(archivePath, 0, NULL);
if (archive) {
// 获取压缩包中的条目数
int numEntries = zip_get_num_entries(archive, 0);
// 遍历压缩包中的每个条目并解压缩
for (int i = 0; i < numEntries; i++) {
const char* entryName = zip_get_name(archive, i, 0);
//extractEntry(archive, entryName, outputPath);
// 获取指定条目在压缩包中的索引
int entryIndex = zip_name_locate(archive, entryName, 0);
if (entryIndex >= 0) {
// 获取指定条目的信息
struct zip_stat entryStat;
zip_stat_init(&entryStat);
zip_stat_index(archive, entryIndex, 0, &entryStat);
// 判断条目类型
if (entryStat.name[strlen(entryStat.name) - 1] == '/') {
// 如果是文件夹,则创建对应的目录
std::string folderPath = outputPath;
folderPath += "/";
folderPath += entryName;
WCHAR wszClassName[256];
memset(wszClassName, 0, sizeof(wszClassName));
MultiByteToWideChar(CP_ACP, 0, folderPath.c_str(), strlen(folderPath.c_str()) + 1, wszClassName, sizeof(wszClassName) / sizeof(wszClassName[0]));
CreateDirectory(wszClassName,NULL);
}
else {
// 如果是文件,则解压缩该文件
zip_file* file = zip_fopen_index(archive, entryIndex, 0);
if (file) {
// 创建输出文件流
std::string filePath = outputPath;
filePath += "/";
filePath += entryName;
std::ofstream outputFile(filePath, std::ios::binary);
if (outputFile) {
// 创建缓冲区来存储文件内容
unsigned char* buffer = new unsigned char[entryStat.size];
// 读取文件内容到缓冲区
zip_fread(file, buffer, entryStat.size);
// 将缓冲区内容写入输出文件流
outputFile.write(reinterpret_cast<const char*>(buffer), entryStat.size);
outputFile.close();
// 删除缓冲区内存
delete[] buffer;
}
// 关闭文件流
zip_fclose(file);
}
}
}
}
// 关闭压缩包
zip_close(archive);
}
}