zlib minizip 压缩和解压目录

7 篇文章 0 订阅

原创文章禁止转载 同步发布http://www.alom.com.cn/

压缩代码

zipHelper.h

#pragma once
#ifndef ZIPHELPER_H
#define ZIPHELPER_H
#include <string>
#include "zlib\unzip.h"
#include "zlib\zip.h"

class ZipHelper
{
public:
    // 压缩文件/文件夹
    bool ZipDir(const std::string& sourcePath, const std::string& zipPath);
    ZipHelper();
    ~ZipHelper();
private:
    bool AddFileToZip(zipFile zf, const std::string& relative, const std::string& sourcePath);
    bool AddDirToZip(zipFile zf, const std::string& relative);
    // 
    bool InnerWriteFileToZip(zipFile zf, const std::string& path);
};
#endif // ZIPHELPER_H

zipHelper.cpp

#define _CRT_SECURE_NO_WARNINGS

#include "unzipHelper.h"
#include <boost/filesystem.hpp>
#include "logs.h"

ZipHelper::ZipHelper()
{

}

ZipHelper::~ZipHelper()
{

}

bool ZipHelper::AddFileToZip(zipFile zf, const std::string& relativeInZip, const std::string& sourcePath)
{
    FILE* fps{ NULL };
    int err{ ZIP_ERRNO };
    bool ret{ false };
    zip_fileinfo zi { 0 };
    memset(&zi, 0, sizeof(zip_fileinfo));
    std::string newFileName{ relativeInZip };
    err = zipOpenNewFileInZip(zf, newFileName.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
    if (ZIP_OK != err)
    {
        LOG_ERROR("add error!");
        return false;
    }
    ret = InnerWriteFileToZip(zf, sourcePath);
    err = zipCloseFileInZip(zf);
    return ret && (ZIP_OK == err);
}


bool ZipHelper::AddDirToZip(zipFile zf, const std::string& relative)
{
    zip_fileinfo zi{ 0 };
    memset(&zi, 0, sizeof(zip_fileinfo));
    int ret{ ZIP_ERRNO };
    std::string newRelative { relative + "/" };
    ret = zipOpenNewFileInZip(zf, newRelative.c_str(), &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
    if (ZIP_OK != ret)
    {
        return false;
    }
    ret = zipCloseFileInZip(zf);
    return ret == ZIP_OK;
}

bool ZipHelper::InnerWriteFileToZip(zipFile zf, const std::string& path)
{
    FILE* fps = fopen(path.c_str(), "rb");
    if (NULL == fps)
    {
        return false;
    }
    int err{ ZIP_ERRNO };
    do
    {
        enum {MAX_BUFFER = 40960 };
        char buf[MAX_BUFFER];
        size_t nRead{ 0 };
        while (!feof(fps))
        {
            nRead = fread(buf, 1, sizeof(buf), fps);
            err = zipWriteInFileInZip(zf, buf, nRead);
            if (ZIP_OK != err)
            {
                break;
            }
            if (ferror(fps))
            {
                err = ZIP_ERRNO;
                break;
            }
        }
    } while (0);
    fclose(fps);
    return ZIP_OK == err;
}

//目录或者文件压缩为zip文件
bool ZipHelper::ZipDir(const std::string& sourcePath, const std::string& zipPath)
{
    if (!boost::filesystem::exists(sourcePath))
    {
        return false;
    }
    int ret { ZIP_ERRNO };
    boost::filesystem::path home{sourcePath};
    zipFile zf = zipOpen(zipPath.c_str(), APPEND_STATUS_CREATE);    
    if (boost::filesystem::is_directory(sourcePath))
    {
        // AddFileToZip(newZipFile, home.filename().string(), "");
        boost::filesystem::recursive_directory_iterator it;
        for (auto& it : boost::filesystem::recursive_directory_iterator(home))
        {
            boost::filesystem::path relative = boost::filesystem::relative(it.path(), home);
            if (boost::filesystem::is_directory(it.path()))
            {
                AddDirToZip(zf, relative.string());
            }
            else
            {
                AddFileToZip(zf, relative.string(), it.path().string());
            }
        }
    }
    else if (boost::filesystem::is_regular_file(sourcePath))
    {
        AddFileToZip(zf, home.filename().string(), home.string());
    }
    else
    {
        return false;
    }
    ret = zipClose(zf, NULL); //关闭zip文件  
    return ZIP_OK == ret;
}

解压代码

unzipHelper.h

#pragma once
#ifndef UNZIPHELPER_H
#define UNZIPHELPER_H
#include <string>
#include "zlib\unzip.h"
#include "zlib\zip.h"
class UnZipHelper
{
public:
    UnZipHelper();
    ~UnZipHelper();
    // 解压到文件夹
    bool UnzipDir(const std::string& unpackPath, const std::string& zipFilePath);
private:
    bool MakeDir(const std::string& path);
    int UnzipOneFile(unzFile uf, const unz_file_info& info, const std::string& path);
};

#endif // UNZIPHELPER_H

unzipHelper.cpp

#include "unzipHelper.h"
#include "logs.h"
//#if __cplusplus >= 201703L
//#include <filesystem>
//#else
#include <boost/filesystem.hpp>
//#endif 


#pragma comment(lib, "zlibwapi.lib")


#define BUF_MAX 65535
#define  MAX_PATH 260


UnZipHelper::UnZipHelper()
{

}

UnZipHelper::~UnZipHelper()
{

}
bool UnZipHelper::UnzipDir(const std::string& unpackPath, const std::string& zipFilePath)
{
//#if __cplusplus >= 201703L
//#else
//#endif 
    const char* pwd{ NULL };
    unzFile uf = unzOpen(zipFilePath.c_str());
    unz_global_info64 gi;
    int err{ ZIP_ERRNO };
    if (uf == NULL)
    {
        LOG_ERROR("unzOpen %s error!", zipFilePath.c_str());
        return false;
    }
    if (!MakeDir(unpackPath))
    {
        return false;
    }
    boost::filesystem::path root{ unpackPath };
    int nRet = unzGoToFirstFile(uf);
    while (nRet == UNZ_OK)
    {
        char szRelative[MAX_PATH];
        unz_file_info unZipFileInfo;
        err = unzGetCurrentFileInfo(uf, &unZipFileInfo, szRelative, sizeof(szRelative), NULL, 0, NULL, 0);
        if (err != UNZ_OK)
        {
            LOG_ERROR("error %d with zipfile in unzGetCurrentFileInfo\n", err);
            break;
        }
        boost::filesystem::path relative(szRelative);
        int l = strlen(szRelative);
        if ('\\' == szRelative[l - 1] || '/' == szRelative[l - 1])
        {
            // 文件夹 
            auto path = root / relative;
            if (!MakeDir(path.string()))
            {
                return false;
            }
            nRet = unzGoToNextFile(uf);
            continue;
        }
        // 文件
        auto path = root / relative;
        
        if (!MakeDir(path.parent_path().string()))
        {
            return false;
        }
        err = UnzipOneFile(uf, unZipFileInfo, path.string());
        if (UNZ_OK != err)
        {
            LOG_ERROR("UnzipOneFile %d", err);
        }
        nRet = unzGoToNextFile(uf);
    }
    bool res{ false };
    if (UNZ_OK == err && UNZ_END_OF_LIST_OF_FILE == nRet )
    {
        res = true;
    }
    err = unzClose(uf);
    if (UNZ_OK != err)
    {
        LOG_ERROR("unzClose %d", err);
    }
    return res;
}

int UnZipHelper::UnzipOneFile(unzFile uf, const unz_file_info& info, const std::string& path)
{
    int err = unzOpenCurrentFilePassword(uf, NULL);
    if (UNZ_OK != err)
    {
        return err;
    }
    FILE * pFile;
    fopen_s(&pFile, path.c_str(), "wb");
    if (NULL == pFile)
    {
        LOG_ERROR("fopen %s error!", path.c_str());
        return UNZ_ERRNO;
    }
    enum { MAX_BUFFER = 256 };
    char buffer[MAX_BUFFER];
    // 文件信息,后期加上
    size_t size = info.uncompressed_size;
    while (size > 0)
    {
        int nRead{ 0 };
        if (size > MAX_BUFFER)
        {
            nRead = MAX_BUFFER;
        }
        else
        {
            nRead = size;
        }
        int nReadBytes = unzReadCurrentFile(uf, buffer, nRead);
        int n = fwrite(buffer, nReadBytes, 1, pFile);
        if (size >= nReadBytes)
        {
            size -= nReadBytes;
        }
        else
        {
            LOG_ERROR("SIZE ERROR!");
            size = 0;
        }
    }
    fclose(pFile);
    err = unzCloseCurrentFile(uf);
    return err;
}

bool UnZipHelper::MakeDir(const std::string& path)
{
    if (boost::filesystem::exists(path))
    {
        if (!boost::filesystem::is_directory(path))
        {
            LOG_ERROR("%s is file", path.c_str());
            return false;
        }
        // LOG_INFO("%s dir is exists!", path.c_str());
        return true;
    }
    if (!boost::filesystem::create_directory(path))
    {
        LOG_ERROR("create dir %s error!", path.c_str());
        return false;
    }
    return true;
}

logs.h

#pragma once

#define LOG_ERROR(fmt, ...) printf("[ERROR] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_WRONG(fmt, ...) printf("[WRONG] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_INFO(fmt, ...)  printf("[INFO] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_TRACE(fmt, ...) printf("[TRACE] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)

#ifdef _DEBUG
#define LOG_DEBUG(fmt, ...) printf("[DEBUG] %s %d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define LOG_DEBUG(fmt, ...) ((void)0)
#endif 
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值