zip

kuba--MIT活跃维护

用 C 写的轻量级 zip 压缩解压库,代码可移植、接口简单,方便嵌进各种 C 项目里处理 zip 文件。

A portable, simple zip library written in C

v0.3.15+miniz.3.1.2发布于 2026-08-01 14:10 UTC1,616star307fork同步于 2026-11-10 11:47 UTC

怎么上手

由 README 提炼,执行前请确认
mkdir build && cd build && cmake -DBUILD_SHARED_LIBS=true .. && cmake --build .
硬件要求按 README 说明

README 未说明,纯 C 库,不涉及 GPU 或显存要求

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

一个可移植的 C 语言 zip 库,只需三个文件就能编进项目,省去引入重型依赖

用 C 写的轻量级 zip 压缩解压库,代码可移植、接口简单,方便嵌进各种 C 项目里处理 zip 文件。

核心能力

  • 基于 miniz 封装,仅需 3 个源文件即可集成
  • 支持把多个文件或缓冲区合并到同一 entry 并即时压缩
  • 提供内存流 API,可直接在内存中创建和读取 zip
  • 支持按名称或索引删除归档内条目
  • 支持传统 PKWARE 加密的密码保护归档

容易踩的坑

README 未给出 CMake 之外的构建方式,非 CMake 项目需自行把 3 个源文件加入编译;密码保护仅支持传统 PKWARE 加密,不是 AES;Go/Rust/Ruby 等语言绑定需自行编译动态库并链接 libzip

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.3.15+miniz.3.1.2
  1. v0.3.15+miniz.3.1.2最新正式版2026-08-01 · 2026-08-01 14:10 UTC

    What's Changed

  2. v0.3.14+miniz.3.1.12026-06-21 · 2026-06-21 12:53 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/kuba--/zip/compare/v0.3.13...v0.3.14+miniz.3.1.1

  3. v0.3.13+miniz.3.1.12026-06-20 · 2026-06-20 16:04 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/kuba--/zip/compare/v0.3.12...v0.3.13+miniz.3.1.1

  4. v0.3.12+miniz.3.1.12026-06-18 · 2026-06-18 10:17 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/kuba--/zip/compare/v0.3.9...v0.3.12+miniz.3.1.1

  5. v0.3.11v0.3.11+miniz.3.1.12026-06-07 · 2026-06-07 12:49 UTC
    查看更新说明

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    A portable (OSX/Linux/Windows/Android/iOS), simple zip library written in C

    This is done by hacking awesome miniz library and layering functions on top of the miniz v3.1.2 API.

    Build

    The Idea

    It was the reason, why I decided to write zip module on top of the miniz. It required a little bit hacking and wrapping some functions, but I kept simplicity. So, you can grab these 3 files and compile them into your project. I hope that interface is also extremely simple, so you will not have any problems to understand it.

    Examples

    • Create a new zip archive with default compression level.
    struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
    {
        zip_entry_open(zip, "foo-1.txt");
        {
            const char *buf = "Some data here...\0";
            zip_entry_write(zip, buf, strlen(buf));
        }
        zip_entry_close(zip);
    
        zip_entry_open(zip, "foo-2.txt");
        {
            // merge 3 files into one entry and compress them on-the-fly.
            zip_entry_fwrite(zip, "foo-2.1.txt");
            zip_entry_fwrite(zip, "foo-2.2.txt");
            zip_entry_fwrite(zip, "foo-2.3.txt");
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    • Append to the existing zip archive.
    struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
    {
        zip_entry_open(zip, "foo-3.txt");
        {
            const char *buf = "Append some data here...\0";
            zip_entry_write(zip, buf, strlen(buf));
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    • Extract a zip archive into a folder.
    int on_extract_entry(const char *filename, void *arg) {
        static int i = 0;
        int n = *(int *)arg;
        printf("Extracted: %s (%d of %d)\n", filename, ++i, n);
    
        return 0;
    }
    
    // From "foo.zip" on disk
    int arg = 2;
    zip_extract("foo.zip", "/tmp", on_extract_entry, &arg);
    
    // Or from memory
    arg = 2;
    zip_stream_extract(zipstream, zipstreamsize, "/tmp", on_extract_entry, &arg);
    
    • Extract a zip entry into memory.
    void *buf = NULL;
    size_t bufsize;
    
    struct zip_t *zip = zip_open("foo.zip", 0, 'r');
    {
        zip_entry_open(zip, "foo-1.txt");
        {
            zip_entry_read(zip, &buf, &bufsize);
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    free(buf);
    
    • Extract a zip entry into memory (no internal allocation).
    unsigned char *buf;
    size_t bufsize;
    
    struct zip_t *zip = zip_open("foo.zip", 0, 'r');
    {
        zip_entry_open(zip, "foo-1.txt");
        {
            bufsize = zip_entry_size(zip);
            buf = calloc(sizeof(unsigned char), bufsize);
    
            zip_entry_noallocread(zip, (void *)buf, bufsize);
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    free(buf);
    
    • Extract a zip entry into memory using callback.
    struct buffer_t {
        char *data;
        size_t size;
    };
    
    static size_t on_extract(void *arg, unsigned long long offset, const void *data, size_t size) {
        struct buffer_t *buf = (struct buffer_t *)arg;
        buf->data = realloc(buf->data, buf->size + size + 1);
        assert(NULL != buf->data);
    
        memcpy(&(buf->data[buf->size]), data, size);
        buf->size += size;
        buf->data[buf->size] = 0;
    
        return size;
    }
    
    struct buffer_t buf = {0};
    struct zip_t *zip = zip_open("foo.zip", 0, 'r');
    {
        zip_entry_open(zip, "foo-1.txt");
        {
            zip_entry_extract(zip, on_extract, &buf);
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    free(buf.data);
    
    • Extract a zip entry into a file.
    struct zip_t *zip = zip_open("foo.zip", 0, 'r');
    {
        zip_entry_open(zip, "foo-2.txt");
        {
            zip_entry_fread(zip, "foo-2.txt");
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    • Create a new zip archive in memory (stream API).
    char *outbuf = NULL;
    size_t outbufsize = 0;
    
    const char *inbuf = "Append some data here...\0";
    struct zip_t *zip = zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
    {
        zip_entry_open(zip, "foo-1.txt");
        {
            zip_entry_write(zip, inbuf, strlen(inbuf));
        }
        zip_entry_close(zip);
    
        /* copy compressed stream into outbuf */
        zip_stream_copy(zip, (void **)&outbuf, &outbufsize);
    }
    zip_stream_close(zip);
    
    free(outbuf);
    
    • Extract a zip entry into memory (stream API).
    char *buf = NULL;
    size_t bufsize = 0;
    
    struct zip_t *zip = zip_stream_open(zipstream, zipstreamsize, 0, 'r');
    {
        zip_entry_open(zip, "foo-1.txt");
        {
            zip_entry_read(zip, (void **)&buf, &bufsize);
        }
        zip_entry_close(zip);
    }
    zip_stream_close(zip);
    
    free(buf);
    
    • Extract a partial zip entry

    Reads up to size bytes of the entry starting at offset into a caller-owned buffer (no internal allocation). size is clamped to the bytes remaining after offset, so it is safe to pass a size larger than what is left in the entry. The call returns the number of bytes actually written, or a negative error code (for example when offset is past the end of the entry).

    unsigned char buf[16];
    size_t bufsize = sizeof(buf);
    
    struct zip_t *zip = zip_open("foo.zip", 0, 'r');
    {
        zip_entry_open(zip, "foo-1.txt");
        {
            size_t offset = 4;
            ssize_t nread = zip_entry_noallocreadwithoffset(zip, offset, bufsize, (void *)buf);
            if (nread < 0) {
                // offset out of range or read error
            }
        }
    
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    • List of all zip entries
    struct zip_t *zip = zip_open("foo.zip", 0, 'r');
    int i, n = zip_entries_total(zip);
    for (i = 0; i < n; ++i) {
        zip_entry_openbyindex(zip, i);
        {
            const char *name = zip_entry_name(zip);
            int isdir = zip_entry_isdir(zip);
            int issymlink = zip_entry_issymlink(zip);
            unsigned long long size = zip_entry_size(zip);
            unsigned int crc32 = zip_entry_crc32(zip);
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    • Compress folder (recursively)
    void zip_walk(struct zip_t *zip, const char *path) {
        DIR *dir;
        struct dirent *entry;
        char fullpath[MAX_PATH];
        struct stat s;
    
        memset(fullpath, 0, MAX_PATH);
        dir = opendir(path);
        assert(dir);
    
        while ((entry = readdir(dir))) {
          // skip "." and ".."
          if (!strcmp(entry->d_name, ".\0") || !strcmp(entry->d_name, "..\0"))
            continue;
    
          snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
          stat(fullpath, &s);
          if (S_ISDIR(s.st_mode))
            zip_walk(zip, fullpath);
          else {
            zip_entry_open(zip, fullpath);
            zip_entry_fwrite(zip, fullpath);
            zip_entry_close(zip);
          }
        }
    
        closedir(dir);
    }
    
    • Delete zip archive entries.
    char *entries[] = {"unused.txt", "remove.ini", "delete.me"};
    // size_t indices[] = {0, 1, 2};
    
    struct zip_t *zip = zip_open("foo.zip", 0, 'd');
    {
        zip_entries_delete(zip, entries, 3);
    
        // you can also delete by index, instead of by name
        // zip_entries_deletebyindex(zip, indices, 3);
    }
    zip_close(zip);
    
    • Create a password-protected zip archive (Traditional PKWARE Encryption).
    struct zip_t *zip = zip_open_with_password("secret.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w', "password");
    {
        zip_entry_open(zip, "secret-1.txt");
        {
            const char *buf = "Classified data...\0";
            zip_entry_write(zip, buf, strlen(buf));
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    • Extract a password-protected zip archive.
    void *buf = NULL;
    size_t bufsize;
    
    struct zip_t *zip = zip_open_with_password("secret.zip", 0, 'r', "password");
    {
        zip_entry_open(zip, "secret-1.txt");
        {
            zip_entry_read(zip, &buf, &bufsize);
        }
        zip_entry_close(zip);
    }
    zip_close(zip);
    
    free(buf);
    
    • Password-protected archive in memory (stream API).
    char *outbuf = NULL;
    size_t outbufsize = 0;
    
    struct zip_t *zip = zip_stream_open_with_password(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w', "password");
    {
        zip_entry_open(zip, "secret-1.txt");
        {
            const char *buf = "Classified data...\0";
            zip_entry_write(zip, buf, strlen(buf));
        }
        zip_entry_close(zip);
    
        zip_stream_copy(zip, (void **)&outbuf, &outbufsize);
    }
    zip_stream_close(zip);
    
    /* read it back */
    void *readbuf = NULL;
    size_t readsize = 0;
    
    zip = zip_stream_open_with_password(outbuf, outbufsize, 0, 'r', "password");
    {
        zip_entry_open(zip, "secret-1.txt");
        {
            zip_entry_read(zip, &readbuf, &readsize);
        }
        zip_entry_close(zip);
    }
    zip_stream_close(zip);
    
    free(readbuf);
    free(outbuf);
    
    • Delete entries from a password-protected archive.
    char *entries[] = {"obsolete.txt", "remove-me.dat"};
    
    struct zip_t *zip = zip_open_with_password("secret.zip", 0, 'd', "password");
    {
        zip_entries_delete(zip, entries, 2);
    }
    zip_close(zip);
    

    Bindings

    Compile zip library as a dynamic library.

    $ mkdir build
    $ cd build
    $ cmake -DBUILD_SHARED_LIBS=true ..
    $ cmake --build .
    
    Go (cgo)

    Third party binding: kuba--/c-go-zip

    package main
    
    /*
    #cgo CFLAGS: -I../src
    #cgo LDFLAGS: -L. -lzip
    #include <zip.h>
    */
    import "C"
    import "unsafe"
    
    func main() {
        path := C.CString("/tmp/go.zip")
        zip := C.zip_open(path, 6, 'w')
    
        entryname := C.CString("test")
        C.zip_entry_open(zip, entryname)
    
        content := "test content"
        buf := unsafe.Pointer(C.CString(content))
        bufsize := C.size_t(len(content))
        C.zip_entry_write(zip, buf, bufsize)
    
        C.zip_entry_close(zip)
    
        C.zip_close(zip)
    }
    
    Rust (ffi)
    extern crate libc;
    use std::ffi::CString;
    
    #[repr(C)]
    pub struct Zip {
        _private: [u8; 0],
    }
    
    #[link(name = "zip")]
    extern "C" {
        fn zip_open(path: *const libc::c_char, level: libc::c_int, mode: libc::c_char) -> *mut Zip;
        fn zip_close(zip: *mut Zip) -> libc::c_void;
    
        fn zip_entry_open(zip: *mut Zip, entryname: *const libc::c_char) -> libc::c_int;
        fn zip_entry_close(zip: *mut Zip) -> libc::c_int;
        fn zip_entry_write(
            zip: *mut Zip,
            buf: *const libc::c_void,
            bufsize: libc::size_t,
        ) -> libc::c_int;
    }
    
    fn main() {
        let path = CString::new("/tmp/rust.zip").unwrap();
        let mode: libc::c_char = 'w' as libc::c_char;
    
        let entryname = CString::new("test.txt").unwrap();
        let content = "test content\0";
    
        unsafe {
            let zip: *mut Zip = zip_open(path.as_ptr(), 5, mode);
            {
                zip_entry_open(zip, entryname.as_ptr());
                {
                    let buf = content.as_ptr() as *const libc::c_void;
                    let bufsize = content.len() as libc::size_t;
                    zip_entry_write(zip, buf, bufsize);
                }
                zip_entry_close(zip);
            }
            zip_close(zip);
        }
    }
    
    Ruby (ffi)

    Install ffi gem.

    $ gem install ffi
    

    Bind in your module.

    require 'ffi'
    
    module Zip
      extend FFI::Library
      ffi_lib "./libzip.#{::FFI::Platform::LIBSUFFIX}"
    
      attach_function :zip_open, [:string, :int, :char], :pointer
      attach_function :zip_close, [:pointer], :void
    
      attach_function :zip_entry_open, [:pointer, :string], :int
      attach_function :zip_entry_close, [:pointer], :void
      attach_function :zip_entry_write, [:pointer, :string, :int], :int
    end
    
    ptr = Zip.zip_open("/tmp/ruby.zip", 6, "w" )
    
    status = Zip.zip_entry_open(ptr, "test")
    
    content = "test content"
    status = Zip.zip_entry_write(ptr, content, content.size())
    
    Zip.zip_entry_close(ptr)
    Zip.zip_close(ptr)
    
    Python (cffi)

    Install cffi package

    $ pip install cffi
    

    Bind in your package.

    import ctypes.util
    from cffi import FFI
    
    ffi = FFI()
    ffi.cdef("""
        struct zip_t *zip_open(const char *zipname, int level, char mode);
        void zip_close(struct zip_t *zip);
    
        int zip_entry_open(struct zip_t *zip, const char *entryname);
        int zip_entry_close(struct zip_t *zip);
        int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
    """
    )
    
    Zip = ffi.dlopen(ctypes.util.find_library("zip"))
    
    ptr = Zip.zip_open("/tmp/python.zip", 6, 'w')
    
    status = Zip.zip_entry_open(ptr, "test")
    
    content = "test content"
    status = Zip.zip_entry_write(ptr, content, len(content))
    
    Zip.zip_entry_close(ptr)
    Zip.zip_close(ptr)
    
    Never (ffi)
    extern "libzip.so" func zip_open(zipname: string, level: int, mode: char) -> c_ptr
    extern "libzip.so" func zip_close(zip: c_ptr) -> void
    
    extern "libzip.so" func zip_entry_open(zip: c_ptr, entryname: string) -> int
    extern "libzip.so" func zip_entry_close(zip: c_ptr) -> int
    extern "libzip.so" func zip_entry_write(zip: c_ptr, buf: string, bufsize: int) -> int
    extern "libzip.so" func zip_entry_fwrite(zip: c_ptr, filename: string) -> int
    
    func main() -> int
    {
        let content = "Test content"
    
        let zip = zip_open("/tmp/never.zip", 6, 'w');
    
        zip_entry_open(zip, "test.file");
        zip_entry_fwrite(zip, "/tmp/test.txt");
        zip_entry_close(zip);
    
        zip_entry_open(zip, "test.content");
        zip_entry_write(zip, content, length(content));
        zip_entry_close(zip);
    
        zip_close(zip);
        0
    }
    
    Ring

    The language comes with RingZip based on this library

    load "ziplib.ring"
    
    new Zip {
        setFileName("myfile.zip")
        open("w")
        newEntry() {
            open("test.c")
            writefile("test.c")
            close()
        }
        close()
    }
    
    Zig
    $ zig build-exe main.zig -lc -lzip
    
    const c = @cImport({
        @cInclude("zip.h");
    });
    
    pub fn main() void {
        var zip = c.zip_open("/tmp/zig.zip", 6, 'w');
        defer c.zip_close(zip);
    
        _ = c.zip_entry_open(zip, "test");
        defer _ = c.zip_entry_close(zip);
    
        const content = "test content";
        _ = c.zip_entry_write(zip, content, content.len);
    }
    
    Odin

    Third party binding: thechampagne/zip-odin

    package main
    
    foreign import lib "system:zip"
    
    import "core:c"
    
    foreign lib {
        zip_open :: proc(zipname : cstring, level : c.int, mode : c.char) -> rawptr ---
    
        zip_close :: proc(zip : rawptr) ---
    
        zip_entry_open :: proc(zip : rawptr, entryname : cstring) -> c.int ---
    
        zip_entry_close :: proc(zip : rawptr) -> c.int ---
    
        zip_entry_write :: proc(zip : rawptr, buf : rawptr, bufsize : c.size_t) -> c.int ---
    }
    
    main :: proc() {
        zip_file := zip_open("odin.zip", 6, 'w')
        defer zip_close(zip_file)
    
        zip_entry_open(zip_file, "test")
        defer zip_entry_close(zip_file)
    
        content := "test content";
        zip_entry_write(zip_file, &content, len(content))
    }
    
    Nim

    Third party binding: thechampagne/nimzip

    $ nim c --passL:-lzip main.nim
    
    proc zip_open(zipname: cstring, level: cint, mode: char): pointer {.importc.}
    proc zip_close(zip: pointer) {.importc.}
    proc zip_entry_open(zip: pointer, entryname: cstring): cint {.importc.}
    proc zip_entry_close(zip: pointer): cint {.importc.}
    proc zip_entry_write(zip: pointer, buf: pointer, bufsize: csize_t): cint {.importc.}
    
    when isMainModule:
      var zip = zip_open("/tmp/nim.zip", 6, 'w')
    
      discard zip_entry_open(zip, "test")
    
      let content: cstring = "test content";
      discard zip_entry_write(zip, content, csize_t(len(content)))
    
      discard zip_entry_close(zip)
      zip_close(zip)
    
    D

    Third party binding: thechampagne/zip-d

    $ dmd -L-lzip main.d
    
    extern(C) void* zip_open(const(char)* zipname, int level, char mode);
    extern(C) void zip_close(void* zip);
    extern(C) int zip_entry_open(void* zip, const(char)* entryname);
    extern(C) int zip_entry_close(void* zip);
    extern(C) int zip_entry_write(void* zip, const(void)* buf, size_t bufsize);
    
    void main()
    {
      void* zip = zip_open("/tmp/d.zip", 6, 'w');
      scope(exit) zip_close(zip);
    
      zip_entry_open(zip, "test");
      scope(exit) zip_entry_close(zip);
    
      string content = "test content";
      zip_entry_write(zip, content.ptr, content.length);
    }
    
    Pascal

    Third party binding: thechampagne/zip-pascal

    program main;
    
    {$linklib c}
    {$linklib zip}
    
    uses ctypes;
    
    function zip_open(zipname:Pchar; level:longint; mode:char):pointer;cdecl;external;
    procedure zip_close(zip:pointer);cdecl;external;
    function zip_entry_open(zip:pointer; entryname:Pchar):longint;cdecl;external;
    function zip_entry_close(zip:pointer):longint;cdecl;external;
    function zip_entry_write(zip:pointer; buf:pointer; bufsize:csize_t):longint;cdecl;external;
    
    const
       content: Pchar = 'test content';
    var
       zip : pointer;
    
    begin
       zip := zip_open('/tmp/pascal.zip', 6, 'w');
    
       zip_entry_open(zip, 'test');
    
       zip_entry_write(zip, content, strlen(content));
       zip_entry_close(zip);
       zip_close(zip);
    end.
    
    lua

    Third party binding: gynt/luamemzip

    -- Loads the luamemzip.dll
    zip = require("luamemzip")
    
    content = "Test content"
    
    z = zip.zip_stream_open(nil, 6, 'w')
    
    zip.zip_entry_open(z, "test.content")
    zip.zip_entry_write(z, content)
    zip.zip_entry_close(z)
    
    data = zip.zip_stream_copy(z)
    
    zip.zip_close(z)
    

    Optional features

    The library supports three compile-time flags to strip unused functionality and reduce binary size. All features are enabled by default -- if you just drop the source files into your project and compile, everything works as before.

    FlagDefaultEffect when disabled (=0)
    ZIP_ENABLE_DEFLATE1Removes compression / archive-writing APIs (zip_entry_write, zip_entry_fwrite, zip_create, zip_entries_delete, …). Write and append modes ('w', 'a', 'd') return an error.
    ZIP_ENABLE_INFLATE1Removes decompression / extraction APIs (zip_entry_read, zip_entry_fread, zip_entry_extract, zip_extract, zip_stream_extract, …). Read mode ('r') returns an error.
    ZIP_HAVE_SYMLINK1 (Unix/macOS), 0 (Windows)When disabled, symlink entries are extracted as regular file copies instead of creating actual symlinks.
    MINIZ_NO_STDIO0When defined, will disable miniz and zip.c's usage of stdio.

    With CMake:

    # Extract-only build (no compression)
    cmake .. -DZIP_ENABLE_DEFLATE=OFF
    
    # Compress-only build (no extraction)
    cmake .. -DZIP_ENABLE_INFLATE=OFF
    
    # Disable symlink support
    cmake .. -DZIP_HAVE_SYMLINK=OFF
    

    Without CMake (compiler flags):

    cc -DZIP_ENABLE_DEFLATE=0 -c zip.c
    

    Or define before including the header:

    #define ZIP_ENABLE_DEFLATE 0
    #include "zip.h"
    

    No ZIP64

    By default, opening an archive for writing with the literal mode character 'w' will enable ZIP64 output. Internally the library sets a write flag when the mode equals the literal 'w':

    mz_uint wflags = (mode == 'w') ? MZ_ZIP_FLAG_WRITE_ZIP64 : 0;
    

    To ensure the produced ZIP archive is NOT ZIP64, use the alternate mode value that selects the same semantic mode but does not compare equal to the literal 'w'. The implementation accepts an alternate value in the switch labels (so the same behavior is selected), but only the literal 'w' triggers the automatic ZIP64 flag.

    Convention:

    • Use 'w' - 64 (integer value 55) when calling zip_open, zip_stream_open, etc., to select write mode without enabling ZIP64.
    • The same pattern applies to other modes: use 'r' - 64, 'a' - 64, 'd' - 64 to pick the non-ZIP64 variants.

    Check out more cool projects which use this library

    • Filament: Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
    • Hermes JS Engine: Hermes is a JavaScript engine optimized for fast start-up of React Native apps on Android. It features ahead-of-time static optimization and compact bytecode.
    • Monster Mash: New Sketch-Based Modeling and Animation Tool.
    • Object-Oriented Graphics Rendering Engine: OGRE is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce games and demos utilising 3D hardware.
    • Open Asset Import Library: A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
    • PowerToys: Set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity.
    • The Ring Programming Language: Innovative and practical general-purpose multi-paradigm language.
    • The V Programming Language: Simple, fast, safe, compiled. For developing maintainable software.
    • TIC-80: TIC-80 is a FREE and OPEN SOURCE fantasy computer for making, playing and sharing tiny games.
    • Urho3D: Urho3D is a free lightweight, cross-platform 2D and 3D game engine implemented in C++ and released under the MIT license. Greatly inspired by OGRE and Horde3D.
    • and more...