All formats

miniz

LanguageC (usable from C++)
LicenseMIT
Repositorygithub.com/richgel999/miniz
Documentationcomments in miniz_zip.h and the examples
Depends onnothing
Read / writeyes / yes, stored and DEFLATE, ZIP64; no encryption

miniz is a small, fast DEFLATE implementation with a zlib-compatible API plus a ZIP reader and writer. Releases include an amalgamated miniz.c + miniz.h pair that you add to your project, so it’s the easiest way to read or write ZIP files in C with no other dependency.

It supports stored and DEFLATE entries and ZIP64, extracts to memory, files or callbacks, and appends to existing archives. It doesn’t support encryption or other compression methods (bzip2, LZMA, Zstandard). All functions take a mz_zip_archive struct that you zero before use.

Installation#

Download the release zip from GitHub releases and add miniz.c and miniz.h to your build. It’s also in vcpkg and Conan:

Shell
vcpkg install miniz

Basic usage: list and extract files#

C
#include "miniz.h"
#include <stdio.h>

int main(void) {
    mz_zip_archive zip;
    mz_zip_zero_struct(&zip);
    if (!mz_zip_reader_init_file(&zip, "in.zip", 0)) {
        fprintf(stderr, "open failed: %s\n",
                mz_zip_get_error_string(mz_zip_get_last_error(&zip)));
        return 1;
    }

    mz_uint n = mz_zip_reader_get_num_files(&zip);
    for (mz_uint i = 0; i < n; i++) {
        mz_zip_archive_file_stat st;
        if (!mz_zip_reader_file_stat(&zip, i, &st)) continue;
        printf("%-40s %10llu -> %10llu%s\n", st.m_filename,
               (unsigned long long)st.m_uncomp_size, (unsigned long long)st.m_comp_size,
               st.m_is_directory ? " (dir)" : "");
    }

    // extract one file to memory
    size_t size;
    char *data = mz_zip_reader_extract_file_to_heap(&zip, "readme.txt", &size, 0);
    if (data) {
        fwrite(data, 1, size, stdout);
        mz_free(data);
    }

    mz_zip_reader_end(&zip);
    return 0;
}

How to create a ZIP file#

C
#include "miniz.h"
#include <string.h>

int write_zip(void) {
    mz_zip_archive zip;
    mz_zip_zero_struct(&zip);
    if (!mz_zip_writer_init_file(&zip, "out.zip", 0)) return 1;

    const char *text = "hello from miniz\n";
    mz_bool ok = mz_zip_writer_add_mem(&zip, "hello.txt", text, strlen(text), MZ_BEST_COMPRESSION);
    // add a file from disk, with no comment
    ok = ok && mz_zip_writer_add_file(&zip, "docs/report.pdf", "report.pdf", NULL, 0, MZ_DEFAULT_LEVEL);

    ok = ok && mz_zip_writer_finalize_archive(&zip);  // writes the central directory
    mz_zip_writer_end(&zip);
    return ok ? 0 : 1;
}

How to extract all files to disk#

C
for (mz_uint i = 0; i < mz_zip_reader_get_num_files(&zip); i++) {
    mz_zip_archive_file_stat st;
    if (!mz_zip_reader_file_stat(&zip, i, &st) || st.m_is_directory) continue;
    // st.m_filename comes from the archive: reject ".." and absolute paths
    if (strstr(st.m_filename, "..") || st.m_filename[0] == '/') continue;
    char out[1024];
    snprintf(out, sizeof(out), "out/%s", st.m_filename);
    // create parent directories of 'out' here (miniz doesn't)
    mz_zip_reader_extract_to_file(&zip, i, out, 0);
}

How to add a file to an existing ZIP#

C
const char *text = "appended\n";
mz_bool ok = mz_zip_add_mem_to_archive_file_in_place("out.zip", "new.txt",
                 text, strlen(text), NULL, 0, MZ_DEFAULT_LEVEL);

This opens the archive, appends the entry and rewrites the central directory. For many files, use mz_zip_writer_init_from_reader once and add them all before finalizing.

Tips#