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

一、libzip 和 zlib 的关

  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);
}
相关推荐
瑞克-桑切斯37 分钟前
ERP 企业生产管理系统部署手册
运维·docker·云原生·容器·eureka
江屿风1 小时前
【Git-组件】【Git入门:从文档灾难到版本掌控】流食般投喂
运维·笔记·git·组件·版本控制
我不会起名字3221 小时前
K8s 节点磁盘打满导致 Pod 被驱逐:4 类占用与回收顺序
运维·kubernetes·k8s·diskpressure·evicted
雪落漂泊2 小时前
Linux进程(五):进程地址空间篇
linux·运维·服务器
瑞克-桑切斯2 小时前
docker mail商城
运维·docker·容器
AR-26710-2 小时前
Linux Day32——网络,ROCE-IB与以太网
linux·运维
不庸.3 小时前
WPScan 实战入门:从 Docker 靶场到弱密码爆破
运维·安全·web安全·docker·容器·安全性测试·wpscan
wdeok3 小时前
Socket编程Tcp
服务器·网络·tcp
千舟软件4 小时前
报修系统对接企业微信和钉钉的3种方式_千舟报修云
服务器·钉钉·企业微信
Decay__5 小时前
SQL Server 数据库全栈运维实战系列 — 合集索引(24 篇)
运维·数据库·sql·mysql·架构