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);
}
相关推荐
Yana.nice23 分钟前
Weblogic日志体系
linux
阿拉斯攀登35 分钟前
内核模块开发:module_init 与模块机制详解
linux·网络·嵌入式硬件·linux驱动
联盛新能源36 分钟前
优得运维斩获中国户用和工商业光储充大会年度优秀运维案例奖
运维
进击切图仔37 分钟前
基于千问的白盒蒸馏操作教学文档
服务器·人工智能·python
阿拉斯攀登1 小时前
字符设备驱动:file_operations 与读写实现
linux·嵌入式·linux驱动·字符设备驱动
阿拉斯攀登1 小时前
嵌入式 Linux 驱动概述:分类、内核模块、开发环境
linux·嵌入式硬件·linux内核·嵌入式·linux驱动
Raina测试3 小时前
Maestro实现IOSUI自动化
运维·自动化
不像程序员的程序媛10 小时前
系统cpu内存负载资源分析
运维·服务器·数据库
Uncertainty!!12 小时前
Ubuntu 22.04 安装超好用中文输入法rime-ice(雾凇拼音)过程记录
linux·ubuntu·中文输入法
ShineWinsu13 小时前
对于Linux:网络基础的解析
linux·网络·面试·udp·笔试·ip·tcp