minizip库:下载地址

#ifndef ZIP_UTILITIES_H
#define ZIP_UTILITIES_H

#include <list>

namespace ZipUtilities
{
    bool compress_file(const char* zipFilePath, const std::list<const char*>& filePaths,const char* password = nullptr);
    bool decompress_file(const char *zipFilePath, const char *outputFolder, const char* password = nullptr);
}
    
#endif // ZIP_UTILITIES_H
#include "zip_utilities.h"
#include "zip/zip.h"
#include "zip/unzip.h"
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <vector>

bool file_accessible(const char *filename)
{
    return access(filename, F_OK) == 0;
}

const char* getFileName(const char* filePath)
{
    const char* fileName = strrchr(filePath, '/');

    if (fileName == NULL)// 如果未找到斜杠分隔符,可能是Windows系统的路径,尝试查找反斜杠分隔符
    {
        fileName = strrchr(filePath, '\\');
    }

    if (fileName == NULL)// 如果仍未找到分隔符,返回原始路径
    {
        return nullptr;
    }
    else
    {
        return fileName + 1; // 返回文件名部分(去除分隔符)
    }
}

namespace ZipUtilities
{
    ///压缩文件
    bool compress_file(const char* zipFilePath, const std::list<const char*>& filePaths, const char* password)
    {
        if(zipFile zf = zipOpen(zipFilePath, APPEND_STATUS_CREATE))
        {
            for(const char* filePath : filePaths)
            {
                if (file_accessible(filePath))
                {
                    const char * basename = getFileName(filePath);
                    if(!basename)
                    {
                        std::cerr << "压缩错误:无法解析出文件名 " << std::endl;
                        continue;
                    }

                    // 新建压缩文件
                    if((password ?
                        zipOpenNewFileInZip3(zf, basename, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, 0) :
                        zipOpenNewFileInZip(zf, basename, nullptr, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_BEST_COMPRESSION)) == ZIP_OK)
                    {
                        FILE* f = fopen(filePath, "rb");// 读取文件并压缩
                        char buf[1024];
                        int len;
                        while((len = fread(buf, 1, sizeof(buf), f)) > 0)
                        {
                            zipWriteInFileInZip(zf, buf, len);
                        }
                        fclose(f);

                        zipCloseFileInZip(zf);
                    }
                    else
                    {
                        std::cerr << "压缩错误:添加 " << filePath << " 到 " << zipFilePath << std::endl;
                        zipClose(zf, nullptr);
                        return false;
                    }
                }
            }

            zipClose(zf, nullptr);
            return true;
        }
        else
        {
            std::cerr << "压缩错误:打开文件: " << zipFilePath << std::endl;
            return false;
        }
    }

    /// 解压文件
    /// 参数1:zip文件路径
    /// 参数2:解压后的文件保存的目录
    bool decompress_file(const char *zipFilePath, const char *outputFolder, const char* password)
    {
        unzFile zipFile = unzOpen(zipFilePath);
        if (zipFile == NULL)
        {
            std::cerr << "解压错误:打开zip文件失败" << std::endl;
            return false;
        }

        unz_global_info globalInfo;
        if (unzGetGlobalInfo(zipFile, &globalInfo) != UNZ_OK)
        {
            std::cerr << "解压错误:无法获取ZIP文件的全局信息" << std::endl;
            unzClose(zipFile);
            return false;
        }

        if (unzGoToFirstFile(zipFile) != UNZ_OK)
        {
            std::cerr << "解压错误:无法转到ZIP中的第一个文件" << std::endl;
            unzClose(zipFile);
            return false;
        }

        do
        {
            char filename[256];
            unz_file_info fileInfo;

            if (unzGetCurrentFileInfo(zipFile, &fileInfo, filename, sizeof(filename), NULL, 0, NULL, 0) != UNZ_OK)
            {
                std::cerr << "解压错误:无法获取当前文件信息" << std::endl;
                unzClose(zipFile);
                return false;
            }

            std::string outputPath = std::string(outputFolder) + "/" + filename;
            FILE* outputFile = fopen(outputPath.c_str(), "wb");

            if (outputFile == NULL)
            {
                std::cerr << "解压错误:无法创建输出文件" << std::endl;
                unzClose(zipFile);
                return false;
            }

            if ((password ?
                unzOpenCurrentFilePassword(zipFile, password) :
                unzOpenCurrentFile(zipFile)) != UNZ_OK)
            {
                std::cerr << "解压错误:无法在ZIP中打开当前文件" << std::endl;
                fclose(outputFile);
                unzClose(zipFile);
                return false;
            }

            char buffer[1024];
            int readSize;

            do
            {
                readSize = unzReadCurrentFile(zipFile, buffer, sizeof(buffer));
                if (readSize < 0)
                {
                    std::cerr << "解压错误:读取文件数据失败" << std::endl;
                    fclose(outputFile);
                    unzCloseCurrentFile(zipFile);
                    unzClose(zipFile);
                    return false;
                }

                if (readSize > 0)
                {
                    fwrite(buffer, 1, readSize, outputFile);
                }
            } while (readSize > 0);

            fclose(outputFile);
        } while (unzGoToNextFile(zipFile) == UNZ_OK);

        unzClose(zipFile);
        return true;
    }
}

使用:

//无密码压缩文件

    std::string zipfile = "D:/icon/huaji222000.zip";//待生成的压缩文件名称
    std::list<const char *> list;
    list.push_back("D:/icon/huaji.png");
    list.push_back("D:/icon/dog.jpeg");
    list.push_back("D:/icon/color.jpeg");
    list.push_back("D:/icon/a.png");

    ZipUtilities::compress_file(zipfile.c_str(),list);

//解压缩
    ZipUtilities::decompress_file("D:/icon/huaji222000.zip","D:/icon/4444");

//有密码压缩文件
    std::list<const char *> list;
    list.push_back("D:/icon/huaji.png");
    list.push_back("D:/icon/dog.jpeg");
    list.push_back("D:/icon/color.png");
    list.push_back("D:/icon/a.png");

    auto zipfile = "D:/icon/huaji222000_password.zip";//待生成的压缩文件名称
    ZipUtilities::compress_file(zipfile,list,"888555222");

解压缩
    ZipUtilities::decompress_file("D:/icon/huaji222000_password.zip","D:/icon/6666","888555222");

如果文件名中有中文会失败,此问题暂未解决。

03-04 18:49