1.概述
zip格式是使用非常广泛的压缩文件格式。本文主要对libzip(http://www.nih.at/libzip/)的压缩和解压方法的使用进行分析和说明。libzip依赖于zlib,而zlib压缩本身主要处理gzip数据流,虽然其中有minizip可以进行zip文件的操作,看过其中的代码之后感觉有点复杂。而libzip依赖于zlib,但做了一定的封装,提供的接口比较简单,当然libzip也继承了很多开源软件的特性,文档就是一坨屎。
2.libzip编译安装
在其网站上下载源代码,“开源软件三步走”,configure && make && make install,进行编译安装。然后通过man libzip可以看看压缩、解压需要的函数。
3.libzip压缩文件
利用libzip压缩文件时,主要用到的头文件有zip.h,以及zipconf.h(定义类型的头文件)但是该文件没有作为标准头文件放置到/usr/src/include目录中(或者其它安装目录),因此在编译的时候,需要指定查找目录。No say, Show code。
压缩文件基本流程为:
(1)通过zip_open创建一个压缩文件;
(2)通过zip_source_file打开需要压缩的文件;
(3)通过zip_file_add将文件添加到压缩文件中。
#include <stdio.h> #include <zipconf.h> #include <zip.h> #include <stdlib.h> #define ZIPFILE_NAME "testzip.zip" #define SRCFILE_NAME "test.txt" #define FILENAME_IN_ZIP "test.txt" int main(int argc, char *argv[]) { int iErr = 0; struct zip * zipfile = NULL; struct zip_source * srcfile = NULL; zipfile = zip_open(ZIPFILE_NAME, ZIP_CREATE | ZIP_TRUNCATE, &iErr); if(!zipfile) { printf("zip open failed:%d\n", iErr); exit(EXIT_FAILURE); } //open a file for zip source srcfile = zip_source_file(zipfile, SRCFILE_NAME, 0, -1); if(!srcfile) { printf(" open source file failed\n"); zip_close(zipfile); exit(EXIT_FAILURE); } //add file zip_file_add(zipfile, FILENAME_IN_ZIP, srcfile, ZIP_FL_OVERWRITE); zip_close(zipfile); return 0; }
需要注意的是,在 zip_file_add的时候,已经关闭了sourcefile,如果再次关闭,会报错。
4.libzip解压文件
基本流程为:
(1)通过zip_open打开一个压缩文件,通过zip_get_num_entries获得压缩文件中条目数目(即:其中压缩文件的数目);
(2)遍历每个条目,通过zip_stat_index获得条目的基本信息;
(3)通过zip_fopen_index打开条目,通过zip_fread读取其中的数据,读出的数据为解压后的数据;
(4)创建本地文件,将解压后的数据流写入即可。
#include <stdio.h> #include <zipconf.h> #include <zip.h> #include <stdlib.h> #include <inttypes.h> #include <string.h> #define ZIPFILE_NAME "testzip.zip" int main(int argc, char *argv[]) { int iErr = 0; struct zip * zipfile = NULL; struct zip_file *entries = NULL; struct zip_stat stat; zip_int64_t i64Num = 0; zip_int64_t i64Count = 0; int iRead = 0; int iLen = 0; char buf[1024]; memset(&stat, 0, sizeof(stat)); memset(buf, 0, sizeof(buf)); zipfile = zip_open(ZIPFILE_NAME, ZIP_CHECKCONS, &iErr); if(!zipfile) { printf("zip open failed:%d\n", iErr); exit(EXIT_FAILURE); } //get how many entrrites in archive i64Num = zip_get_num_entries(zipfile, 0); for (i64Count = 0; i64Count < i64Num; i64Count++) { if (zip_stat_index(zipfile, i64Count, 0, &stat) == 0) { printf("the file name is:%s\n", stat.name); } entries = zip_fopen_index(zipfile, i64Count, 0); if (!entries) { printf("fopen index failed\n"); goto End; } //create the original file FILE *fp = fopen(stat.name, "w+"); if (!fp) { printf("create local file failed\n"); goto End; } while(iLen < stat.size) { iRead = zip_fread(entries, buf, 1024); if (iRead < 0) { printf("read file failed\n"); fclose(fp); goto End; } fwrite(buf, 1, iRead, fp); iLen += iRead; } fclose(fp); } End: zip_close(zipfile); return 0; }
最后还是那句俗得不能再俗的话,“本人水平有限,错误在所难免,欢迎批评指正。”
5.参考文献
【1】http://www.nih.at/libzip/index.html
【2】http://www.zlib.net/zlib_faq.html
【3】https://gist.github.com/mobius/1759816