Linux c 在内存中创建zip,最后写入测试

一、libzipzlib 的关

  1. zlib 是一个底层的数据压缩库,它实现了 DEFLATE 压缩算法。它本身不处理 ZIP 文件格式。
  2. libzip 是一个用于创建和操作 ZIP 归档文件的库。ZIP 文件格式内部使用 DEFLATE 算法进行压缩。
  3. libzip 依赖于 zlib 来执行实际的压缩工作。当你用 libzip 添加一个文件时,它会自动调用 zlib 来压缩数据,然后将压缩后的数据写入 ZIP 归档的正确位置。

二、使用libzip 在压缩内存中的数据,同时zip 压缩文件也保存在内存中

复制代码
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <sstream>

#include <zip.h>
static int use_data(void *pbtZipData, size_t nZipData, const char *pstrFileName)
{
    /* example implementation that writes pbtZipData to file */
    FILE *fp;

    if (pbtZipData == NULL) {
        if (remove(pstrFileName) < 0 && errno != ENOENT) {
            fprintf(stderr, "can't remove %s: %s\n", pstrFileName, strerror(errno));
            return -1;
        }
        return 0;
    }

    if ((fp = fopen(pstrFileName, "wb")) == NULL) {
        fprintf(stderr, "can't open %s: %s\n", pstrFileName, strerror(errno));
        return -1;
    }
    if (fwrite(pbtZipData, 1, nZipData, fp) < nZipData) {
        fprintf(stderr, "can't write %s: %s\n", pstrFileName, strerror(errno));
        fclose(fp);
        return -1;
    }
    if (fclose(fp) < 0) {
        fprintf(stderr, "can't write %s: %s\n", pstrFileName, strerror(errno));
        return -1;
    }

    return 0;
}

bool AddFilesToZip(zip_t* pZipHandle, const char* pstrFileName, const char* pstrData)
{
    if(pZipHandle && pstrData && pstrFileName){
        zip_source_t* pstZipSource = zip_source_buffer(pZipHandle, pstrData, strlen(pstrData), 0);
        if (zip_file_add(pZipHandle, pstrFileName, pstZipSource, ZIP_FL_ENC_UTF_8) >= 0) {
            return true;
        }
        else{
            std::cerr << "nZipError adding source: " << zip_strerror(pZipHandle) << std::endl;
        }
    }
    
    return false;
}

int main()
{
    zip_error_t nZipError;
    zip_error_init(&nZipError);

    zip_source_t* pstZipSource = zip_source_buffer_create(NULL, 0, 1, &nZipError);
    if (pstZipSource == NULL) {
        std::cerr << "can't create source: " << zip_error_strerror(&nZipError) << std::endl;
        zip_error_fini(&nZipError);
        return 1;
    }

    zip_t* pZipHandle = zip_open_from_source(pstZipSource, ZIP_TRUNCATE, &nZipError);
    if ((pZipHandle ) == NULL) {
        std::cerr << "can't open zip from source: " << zip_error_strerror(&nZipError) << std::endl;
        zip_source_free(pstZipSource);
        zip_error_fini(&nZipError);
        return 1;
    }

    zip_error_fini(&nZipError);

    zip_source_keep(pstZipSource);

    if (!AddFilesToZip(pZipHandle, "123.log"/*测试, 压缩包内部文件*/, "tt"/*测试, 文件内容*/)){
        return 1;
    }

    if (zip_close(pZipHandle) < 0) {
        std::cerr << "can't close zip pstrFileName" << zip_strerror(pZipHandle) << std::endl;
        return 1;
    }


    //测试, 主要拿到zip 二进制数据,保存文件。参考 examples/in-memory.c
    unsigned char* pbtZipData = NULL;
    int nZipData = 0;
    if (!zip_source_is_deleted(pstZipSource)) {
        zip_stat_t zst;

        if (zip_source_stat(pstZipSource, &zst) < 0) {
            fprintf(stderr, "can't stat source: %s\n", zip_error_strerror(zip_source_error(pstZipSource)));
            return 1;
        }

        nZipData = zst.size;

        if (zip_source_open(pstZipSource) < 0) {
            fprintf(stderr, "can't open source: %s\n", zip_error_strerror(zip_source_error(pstZipSource)));
            return 1;
        }
        if ((pbtZipData = (unsigned char*)malloc(nZipData)) == NULL) {
            fprintf(stderr, "malloc failed: %s\n", strerror(errno));
            zip_source_close(pstZipSource);
            return 1;
        }
        if ((zip_uint64_t)zip_source_read(pstZipSource, pbtZipData, nZipData) < nZipData) {
            fprintf(stderr, "can't read pbtZipData from source: %s\n", zip_error_strerror(zip_source_error(pstZipSource)));
            zip_source_close(pstZipSource);
            free(pbtZipData);
            return 1;
        }
        zip_source_close(pstZipSource);
    }

    /* we're done with pstZipSource */
    zip_source_free(pstZipSource);

    /* use new pbtZipData */
    use_data(pbtZipData, nZipData, "123.zip"/*测试, 压缩包文件名*/);

    free(pbtZipData);
}
相关推荐
en.en..1 小时前
Linux 孤儿进程与僵尸进程
linux·运维·服务器
一只积极向上的小咸鱼5 小时前
Codex Remote SSH / Dev Container 无限转圈与 GPT-6 可用问题排查总结
运维·gpt·ssh
智塑未来5 小时前
自动化立体库工业无线通信:AGV、AMR、RGV、穿梭车、无人叉车、堆垛机全覆盖
运维·自动化
T1mzhou6 小时前
ARM64 Linux 6.10内核启动流程7-ioremap和readl writel
linux·服务器·c语言
小羊没烦恼!7 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
Elastic 中国社区官方博客7 小时前
教程:使用 ES|QL 进行威胁狩猎
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索·安全威胁分析
bwz999@88.com7 小时前
Ubuntu Server 24.04 设置中文
linux·运维·ubuntu
fly-977 小时前
Ubuntu FTP/SFTP 报错:找不到匹配的 hostkey 算法 完整解决
linux·ubuntu
Cx330❀8 小时前
【Linux网络】网络层协议 IP :从网络层原理到 Linux 内核源码
linux·运维·服务器·网络·tcp/ip·ai·ai编程