复制代码
#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);
}