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);
}
相关推荐
小二李12 小时前
第11章 nestjs服务端开发:登录鉴权
运维·服务器
i建模13 小时前
如何在Arch Linux中重设忘记的root密码
linux·运维·服务器
chatexcel14 小时前
元空AI+Clawdbot:7×24 AI办公智能体新形态详解(长期上下文/自动化任务/工具粘合)
运维·人工智能·自动化
kida_yuan14 小时前
【Linux】运维实战笔记 — 我常用的方法与命令
linux·运维·笔记
@syh.14 小时前
【linux】进程控制
linux
何中应16 小时前
vmware的linux虚拟机如何设置以命令行方式启动
linux·运维·服务器
野犬寒鸦16 小时前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端·学习
江畔何人初16 小时前
kubernet与docker的关系
linux·运维·云原生
bubuly17 小时前
软件开发全流程注意事项:从需求到运维的全方位指南
大数据·运维·数据库
百炼成神 LV@菜哥17 小时前
Kylin Linux V10 aarch64 安装启动 TigerVNC-Server
linux·服务器·kylin