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");
如果文件名中有中文会失败,此问题暂未解决。