Работа с ZIP/архивами в C++: библиотека libzip и zlib

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с ZIP-архивами в C++: libzip и zlib

В современной разработке на C++ часто возникает необходимость упаковывать и распаковывать данные. ZIP-архивы остаются одним из самых популярных форматов благодаря своей универсальности и поддержке сжатия. В этой статье мы рассмотрим две ключевые библиотеки для работы с ZIP в C++: libzip (высокоуровневая работа с архивами) и zlib (низкоуровневое сжатие). Вы узнаете, как установить библиотеки, создать архив, извлечь файлы и прочитать содержимое без распаковки.

Основные библиотеки для работы с ZIP в C++

  • libzip — кроссплатформенная библиотека для создания, чтения и модификации ZIP-архивов. Поддерживает шифрование, потоки и работу с памятью.
  • zlib — низкоуровневая библиотека сжатия данных (алгоритм Deflate). Используется как основа для libzip и других архиваторов.
  • minizip — легковесная обёртка над zlib для работы с ZIP-форматом (часто входит в состав 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: Создание ZIP-архива с помощью libzip

Создадим архив 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;

        // Открываем файл внутри архива
        zip_file_t* zf = zip_fopen_index(archive, i, 0);
        if (!zf) {
            std::cerr << "Не удалось открыть файл: " << filename << std::endl;
            continue;
        }

        // Читаем и записываем данные
        std::                    

Рекомендаций