c++解压压缩包文件

功能实现需要依赖相关头文件和库文件,我这里的是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);
}


工程的“包含目录”和“库目录”需要包含相关路径
c++解压压缩包文件_第1张图片

程序运行可能还需要依赖当前exe路径下相关dll文件
c++解压压缩包文件_第2张图片


后续发现上面代码的方法,遇到压缩包中有文件夹的,会解压失败。
可以尝试下面这种方法,亲测可行:

#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);
    }
}

你可能感兴趣的:(c++,开发语言)