一、libzip
和 zlib
的关
- zlib 是一个底层的数据压缩库,它实现了 DEFLATE 压缩算法。它本身不处理 ZIP 文件格式。
- libzip 是一个用于创建和操作 ZIP 归档文件的库。ZIP 文件格式内部使用 DEFLATE 算法进行压缩。
- 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.cunsigned 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);
}