Working with ZIP Archives in C++: libzip and zlib
In modern C++ development, the need to pack and unpack data often arises. ZIP archives remain one of the most popular formats due to their versatility and compression support. In this article, we will look at two key libraries for working with ZIP in C++: libzip (high-level archive handling) and zlib (low-level compression). You will learn how to install the libraries, create an archive, extract files, and read contents without unpacking.
Core Libraries for Working with ZIP in C++
- libzip — a cross-platform library for creating, reading, and modifying ZIP archives. Supports encryption, streams, and memory operations.
- zlib — a low-level data compression library (Deflate algorithm). Used as a foundation for libzip and other archivers.
- minizip — a lightweight wrapper over zlib for working with the ZIP format (often included as part of zlib).
For most tasks, it is recommended to use libzip as it provides a more convenient and secure API.
Installing the Libraries
On Linux (Ubuntu/Debian), installation is done via the package manager:
sudo apt-get install libzip-dev zlib1g-devFor macOS (Homebrew):
brew install libzip zlibOn Windows, you can use vcpkg or download pre-built binaries from the official websites.
Integration in CMakeLists.txt:
find_package(ZLIB REQUIRED)find_package(LibZip REQUIRED)target_link_libraries(your_project ZLIB::ZLIB libzip::zip)Example 1: Creating a ZIP Archive with libzip
Let's create an archive example.zip and add a text file to it:
#include <zip.h>#include <iostream>#include <string>
int main() { const char* archive_name = "example.zip"; int err = 0;
// Open archive for writing zip_t* archive = zip_open(archive_name, ZIP_CREATE | ZIP_TRUNCATE, &err); if (!archive) { std::cerr << "Error creating archive: " << err << std::endl; return 1; }
// Data to write const char* filename = "hello.txt"; const char* content = "Hello, world! Hello, C++!"; // Create a data source from memory zip_source_t* source = zip_source_buffer(archive, content, strlen(content), 0); if (!source) { std::cerr << "Error creating source" << std::endl; zip_close(archive); return 1; }
// Add file to archive zip_int64_t index = zip_file_add(archive, filename, source, ZIP_FL_OVERWRITE); if (index < 0) { std::cerr << "Error adding file: " << zip_strerror(archive) << std::endl; zip_source_free(source); zip_close(archive); return 1; }
// Close archive zip_close(archive); std::cout << "Archive created: " << archive_name << std::endl; return 0;}Example 2: Extracting a ZIP Archive
Extract all files from the archive to the current directory:
#include <zip.h>#include <iostream>#include <fstream>
int main() { const char* archive_name = "example.zip"; int err = 0;
// Open archive for reading zip_t* archive = zip_open(archive_name, 0, &err); if (!archive) { std::cerr << "Error opening archive: " << 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) { // Get file name const char* filename = zip_get_name(archive, i, 0); if (!filename) continue;
// Open fi