在 C++ 中使用 ZIP 压缩包:libzip 和 zlib
在现代 C++ 开发中,经常需要打包和解压数据。ZIP 压缩包因其通用性和压缩支持而成为最流行的格式之一。在本文中,我们将介绍两个在 C++ 中处理 ZIP 的关键库:libzip(高级压缩包处理)和 zlib(低级压缩)。您将学习如何安装这些库、创建压缩包、提取文件以及在不解压的情况下读取内容。
在 C++ 中处理 ZIP 的主要库
- libzip — 用于创建、读取和修改 ZIP 压缩包的跨平台库。支持加密、流和内存操作。
- zlib — 低级数据压缩库(Deflate 算法)。用作 libzip 和其他压缩工具的基础。
- minizip — 用于处理 ZIP 格式的轻量级 zlib 封装(通常包含在 zlib 中)。
对于大多数任务,建议使用 libzip,因为它提供了更方便、更安全的 API。
安装库
在 Linux(Ubuntu/Debian)上,通过包管理器安装:
sudo apt-get install libzip-dev zlib1g-dev对于 macOS(Homebrew):
brew install libzip zlib在 Windows 上,可以使用 vcpkg 或从官方网站下载预编译的二进制文件。
在 CMakeLists.txt 中链接:
find_package(ZLIB REQUIRED)find_package(LibZip REQUIRED)target_link_libraries(your_project ZLIB::ZLIB libzip::zip)示例 1:使用 libzip 创建 ZIP 压缩包
创建一个 example.zip 压缩包并向其中添加一个文本文件:
#include <zip.h>#include <iostream>#include <string>
int main() { const char* archive_name = "example.zip"; int err = 0;
// 打开压缩包进行写入 zip_t* archive = zip_open(archive_name, ZIP_CREATE | ZIP_TRUNCATE, &err); if (!archive) { std::cerr << "创建压缩包错误: " << err << std::endl; return 1; }
// 要写入的数据 const char* filename = "hello.txt"; const char* content = "Привет, мир! Hello, C++!"; // 从内存创建数据源 zip_source_t* source = zip_source_buffer(archive, content, strlen(content), 0); if (!source) { std::cerr << "创建数据源错误" << std::endl; zip_close(archive); return 1; }
// 将文件添加到压缩包 zip_int64_t index = zip_file_add(archive, filename, source, ZIP_FL_OVERWRITE); if (index < 0) { std::cerr << "添加文件错误: " << zip_strerror(archive) << std::endl; zip_source_free(source); zip_close(archive); return 1; }
// 关闭压缩包 zip_close(archive); std::cout << "压缩包已创建: " << archive_name << std::endl; return 0;}示例 2:解压 ZIP 压缩包
将压缩包中的所有文件提取到当前目录:
#include <zip.h>#include <iostream>#include <fstream>
int main() { const char* archive_name = "example.zip"; int err = 0;
// 打开压缩包进行读取 zip_t* archive = zip_open(archive_name, 0, &err); if (!archive) { std::cerr << "打开压缩包错误: " << err << std::endl; return 1; }
zip_int64_t num_entries = zip_get_num_entries(archive, 0); for (zip_int64_t i = 0; i < num_entries; ++i) { // 获取文件名 const char* filename = zip_get_name(archive, i, 0); if (!filename) continue;
// 打开文件