zlib解压缩库编译使用
Zlib 是一个广泛使用的、开源的数据压缩库,它实现了 DEFLATE 压缩算法,提供了高效、可靠的数据压缩和解压功能。Zlib 是一个用于数据压缩的软件库,由 Jean-loup Gailly 和 Mark Adler 创建。它实现了 DEFLATE 压缩算法,该算法结合了 LZ77 算法和霍夫曼编码。
·
一、Zlib 库介绍
Zlib 是一个广泛使用的、开源的数据压缩库,它实现了 DEFLATE 压缩算法,提供了高效、可靠的数据压缩和解压功能。Zlib 是一个用于数据压缩的软件库,由 Jean-loup Gailly 和 Mark Adler 创建。它实现了 DEFLATE 压缩算法,该算法结合了 LZ77 算法和霍夫曼编码。
核心特性
- 无损压缩:解压后的数据与原始数据完全相同
- 高性能:压缩和解压速度都很快
- 内存效率:占用内存小,适合嵌入式系统
- 跨平台:支持几乎所有操作系统和编译器
- 开源免费:使用 zlib 许可证,可自由用于商业项目
二、boost库编译
下载Zlib源码包:https://www.zlib.net/zlib131.zip
直接解压缩就行了,找到路径zlib-1.3.1\contrib\vstudio\vc14里面的zlibvc.sln

直接使用Visual Studio打开然后编译就行


然后我们就可以在项目中使用zlib库了,如果需要zip压缩的话,找到zlib-1.3.1\contrib文件夹下minizip,在vs中创建一个项目将该文件夹下的文件添加到项目中,修改配置类型为lib,直接编译即可
然后我们创建一个项目zlib_zip,将头文件添加到项目中
然后将刚刚编译好的库链接到项目中。
三、代码实现
首先,我们需要添加所需要的文件
// 需要的库和头文件
#include "minizip/zip.h" // 压缩功能
#include "minizip/unzip.h" // 解压功能
#include <direct.h> // 目录操作(Windows)
然后我们需要,目录检测与创建
// 使用标准库实现跨平台兼容性
bool directoryExists(const std::string& path) {
struct stat info;
return stat(path.c_str(), &info) == 0 && (info.st_mode & S_IFDIR);
}
// 核心压缩流程
zipFile zf = zipOpen(zipFilename.c_str(), APPEND_STATUS_CREATE);
// ... 文件处理逻辑
zipClose(zf, nullptr);
zip工具类
class ZipUtility {
public:
// 创建标准 zip 文件(只支持文件,不支持目录)
static bool createZip(const std::string& zipFilename,
const std::vector<std::string>& filesToAdd) {
zipFile zf = zipOpen(zipFilename.c_str(), APPEND_STATUS_CREATE);
if (!zf) {
std::cerr << "无法创建 zip 文件: " << zipFilename << std::endl;
return false;
}
bool success = true;
for (const auto& filepath : filesToAdd) {
std::cout << "添加文件到 zip: " << filepath << std::endl;
// 打开要添加的文件
FILE* file = fopen(filepath.c_str(), "rb");
if (!file) {
std::cerr << "无法打开文件: " << filepath << std::endl;
success = false;
continue;
}
// 获取文件大小
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
// 读取文件内容
char* fileData = new char[fileSize];
fread(fileData, 1, fileSize, file);
fclose(file);
// 设置 zip 文件信息
zip_fileinfo zi = { 0 };
// 提取文件名(不带路径)
std::string filename = filepath;
size_t lastSlash = filepath.find_last_of("/\\");
if (lastSlash != std::string::npos) {
filename = filepath.substr(lastSlash + 1);
}
// 在 zip 文件中打开一个新文件
int err = zipOpenNewFileInZip(zf, filename.c_str(), &zi,
nullptr, 0, nullptr, 0, nullptr,
Z_DEFLATED, Z_DEFAULT_COMPRESSION);
if (err != ZIP_OK) {
std::cerr << "无法在 zip 中创建文件条目: " << filename << std::endl;
delete[] fileData;
success = false;
continue;
}
// 写入文件数据
err = zipWriteInFileInZip(zf, fileData, fileSize);
if (err != ZIP_OK) {
std::cerr << "写入 zip 文件失败: " << filename << std::endl;
delete[] fileData;
zipCloseFileInZip(zf);
success = false;
continue;
}
// 关闭 zip 中的文件
zipCloseFileInZip(zf);
delete[] fileData;
}
// 关闭 zip 文件
zipClose(zf, nullptr);
if (success) {
std::cout << "成功创建 zip 文件: " << zipFilename << std::endl;
}
return success;
}
// 解压标准 zip 文件
static bool extractZip(const std::string& zipFilename,
const std::string& outputDir = "") {
// 打开 zip 文件
unzFile uf = unzOpen(zipFilename.c_str());
if (!uf) {
std::cerr << "无法打开 zip 文件: " << zipFilename << std::endl;
return false;
}
// 创建输出目录(如果不存在)
if (!outputDir.empty() && !directoryExists(outputDir)) {
createDirectory(outputDir);
}
unz_global_info gi;
if (unzGetGlobalInfo(uf, &gi) != UNZ_OK) {
std::cerr << "无法读取 zip 文件信息" << std::endl;
unzClose(uf);
return false;
}
std::cout << "zip 文件包含 " << gi.number_entry << " 个文件" << std::endl;
bool success = true;
// 遍历所有文件
for (int i = 0; i < gi.number_entry; i++) {
unz_file_info file_info;
char filename[256];
if (unzGetCurrentFileInfo(uf, &file_info, filename,
sizeof(filename), nullptr, 0, nullptr, 0) != UNZ_OK) {
std::cerr << "无法读取文件信息" << std::endl;
success = false;
continue;
}
std::string outputFilename = outputDir + filename;
std::cout << "解压: " << filename << " -> " << outputFilename << std::endl;
// 打开当前文件进行解压
if (unzOpenCurrentFile(uf) != UNZ_OK) {
std::cerr << "无法打开 zip 中的文件: " << filename << std::endl;
success = false;
continue;
}
// 创建输出文件
FILE* outFile = fopen(outputFilename.c_str(), "wb");
if (!outFile) {
std::cerr << "无法创建输出文件: " << outputFilename << std::endl;
unzCloseCurrentFile(uf);
success = false;
continue;
}
// 读取并写入文件数据
char buffer[8192];
int bytesRead;
while ((bytesRead = unzReadCurrentFile(uf, buffer, sizeof(buffer))) > 0) {
fwrite(buffer, 1, bytesRead, outFile);
}
fclose(outFile);
unzCloseCurrentFile(uf);
// 移动到下一个文件
if (i < gi.number_entry - 1) {
if (unzGoToNextFile(uf) != UNZ_OK) {
std::cerr << "无法移动到下一个文件" << std::endl;
success = false;
break;
}
}
}
unzClose(uf);
if (success) {
std::cout << "解压完成" << std::endl;
}
return success;
}
};
完整代码如下
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sys/stat.h>
#include "minizip/zip.h"
#include "minizip/unzip.h"
#include <direct.h>
// 简单的目录存在检查(跨平台)
bool directoryExists(const std::string& path) {
struct stat info;
return stat(path.c_str(), &info) == 0 && (info.st_mode & S_IFDIR);
}
// 创建目录(跨平台)
bool createDirectory(const std::string& path) {
#ifdef _WIN32
return _mkdir(path.c_str()) == 0;
#else
return mkdir(path.c_str(), 0755) == 0;
#endif
}
class ZipUtility {
public:
// 创建标准 zip 文件(只支持文件,不支持目录)
static bool createZip(const std::string& zipFilename,
const std::vector<std::string>& filesToAdd) {
zipFile zf = zipOpen(zipFilename.c_str(), APPEND_STATUS_CREATE);
if (!zf) {
std::cerr << "无法创建 zip 文件: " << zipFilename << std::endl;
return false;
}
bool success = true;
for (const auto& filepath : filesToAdd) {
std::cout << "添加文件到 zip: " << filepath << std::endl;
// 打开要添加的文件
FILE* file = fopen(filepath.c_str(), "rb");
if (!file) {
std::cerr << "无法打开文件: " << filepath << std::endl;
success = false;
continue;
}
// 获取文件大小
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
// 读取文件内容
char* fileData = new char[fileSize];
fread(fileData, 1, fileSize, file);
fclose(file);
// 设置 zip 文件信息
zip_fileinfo zi = { 0 };
// 提取文件名(不带路径)
std::string filename = filepath;
size_t lastSlash = filepath.find_last_of("/\\");
if (lastSlash != std::string::npos) {
filename = filepath.substr(lastSlash + 1);
}
// 在 zip 文件中打开一个新文件
int err = zipOpenNewFileInZip(zf, filename.c_str(), &zi,
nullptr, 0, nullptr, 0, nullptr,
Z_DEFLATED, Z_DEFAULT_COMPRESSION);
if (err != ZIP_OK) {
std::cerr << "无法在 zip 中创建文件条目: " << filename << std::endl;
delete[] fileData;
success = false;
continue;
}
// 写入文件数据
err = zipWriteInFileInZip(zf, fileData, fileSize);
if (err != ZIP_OK) {
std::cerr << "写入 zip 文件失败: " << filename << std::endl;
delete[] fileData;
zipCloseFileInZip(zf);
success = false;
continue;
}
// 关闭 zip 中的文件
zipCloseFileInZip(zf);
delete[] fileData;
}
// 关闭 zip 文件
zipClose(zf, nullptr);
if (success) {
std::cout << "成功创建 zip 文件: " << zipFilename << std::endl;
}
return success;
}
// 解压标准 zip 文件
static bool extractZip(const std::string& zipFilename,
const std::string& outputDir = "") {
// 打开 zip 文件
unzFile uf = unzOpen(zipFilename.c_str());
if (!uf) {
std::cerr << "无法打开 zip 文件: " << zipFilename << std::endl;
return false;
}
// 创建输出目录(如果不存在)
if (!outputDir.empty() && !directoryExists(outputDir)) {
createDirectory(outputDir);
}
unz_global_info gi;
if (unzGetGlobalInfo(uf, &gi) != UNZ_OK) {
std::cerr << "无法读取 zip 文件信息" << std::endl;
unzClose(uf);
return false;
}
std::cout << "zip 文件包含 " << gi.number_entry << " 个文件" << std::endl;
bool success = true;
// 遍历所有文件
for (int i = 0; i < gi.number_entry; i++) {
unz_file_info file_info;
char filename[256];
if (unzGetCurrentFileInfo(uf, &file_info, filename,
sizeof(filename), nullptr, 0, nullptr, 0) != UNZ_OK) {
std::cerr << "无法读取文件信息" << std::endl;
success = false;
continue;
}
std::string outputFilename = outputDir + filename;
std::cout << "解压: " << filename << " -> " << outputFilename << std::endl;
// 打开当前文件进行解压
if (unzOpenCurrentFile(uf) != UNZ_OK) {
std::cerr << "无法打开 zip 中的文件: " << filename << std::endl;
success = false;
continue;
}
// 创建输出文件
FILE* outFile = fopen(outputFilename.c_str(), "wb");
if (!outFile) {
std::cerr << "无法创建输出文件: " << outputFilename << std::endl;
unzCloseCurrentFile(uf);
success = false;
continue;
}
// 读取并写入文件数据
char buffer[8192];
int bytesRead;
while ((bytesRead = unzReadCurrentFile(uf, buffer, sizeof(buffer))) > 0) {
fwrite(buffer, 1, bytesRead, outFile);
}
fclose(outFile);
unzCloseCurrentFile(uf);
// 移动到下一个文件
if (i < gi.number_entry - 1) {
if (unzGoToNextFile(uf) != UNZ_OK) {
std::cerr << "无法移动到下一个文件" << std::endl;
success = false;
break;
}
}
}
unzClose(uf);
if (success) {
std::cout << "解压完成" << std::endl;
}
return success;
}
};
void printUsage() {
std::cout << "用法:" << std::endl;
std::cout << " 创建zip: tool -c <输出zip文件> <文件或目录1> [文件或目录2] ..." << std::endl;
std::cout << " 解压zip: tool -d <输入zip文件> [输出目录]" << std::endl;
std::cout << "示例:" << std::endl;
std::cout << " tool -c archive.zip file1.txt documents/ images/" << std::endl;
std::cout << " tool -d archive.zip ./output/" << std::endl;
}
int main(int argc, char* argv[]) {
if (argc < 3) {
printUsage();
return 1;
}
std::string mode = argv[1];
if (mode == "-c" || mode == "--compress") {
if (argc < 4) {
std::cerr << "错误: 创建zip需要至少一个输入文件或目录" << std::endl;
printUsage();
return 1;
}
std::string zipFilename = argv[2];
std::vector<std::string> pathsToAdd;
for (int i = 3; i < argc; i++) {
pathsToAdd.push_back(argv[i]);
}
if (!ZipUtility::createZip(zipFilename, pathsToAdd)) {
return 1;
}
}
else if (mode == "-d" || mode == "--decompress") {
std::string zipFilename = argv[2];
std::string outputDir = "";
if (argc >= 4) {
outputDir = argv[3];
// 确保输出目录以路径分隔符结尾
if (outputDir.back() != '/' && outputDir.back() != '\\') {
outputDir += "/";
}
}
if (!ZipUtility::extractZip(zipFilename, outputDir)) {
return 1;
}
}
else {
std::cerr << "错误: 未知模式 '" << mode << "'" << std::endl;
printUsage();
return 1;
}
return 0;
}
编译后我们得到

我们如果要使用这个程序,我们可以使用命令提示符,找到文件所在目录
我们新建一个文件aaa.txt
使用命令
zlib_zip.exe -c archive.zip aaa.txt

我们可以得到
解压缩
zlib_zip.exe -d archive.zip output/


当然这只是一个极其简单的一个解压缩程序,实际上我们还需要考虑大文件处理,多线程压缩等问题
更多推荐


所有评论(0)