【转】使用minizip解压缩多个文件(基于zlib)

原帖子:使用minizip解压缩多个文件(基于zlib)api

写做目的:以前在网上看到不少人在寻找能够解压缩多个文件的程序,其中有尝试zlib的,使用zlib的源码能够生成后缀为点gz的压缩文件,可是一次只能压缩一个文件,没法压缩多个文件。其实,zlib的源码包里有一个第三方的contrib已经实现解压缩多个文件,这就是minizip。下面就来看看是怎么操做的。函数

下载zlib源码
去zlib网站http://www.zlib.net/,下载源码并解压
测试

这里选择tar.gz格式的源码包下载(其它格式均可以)网站


编译zlib
进入到zlib-1.2.11目录下,发现有个Makefile文件,打开以下,
加密

这是个提示,让咱们先运行./configure。按照提示咱们在终端输入./configure并回车,运行完毕后再打开看Makefile,发现里面就有内容了,spa

此时在终端输入make,这样zlib源码就开始编译了。
编译完毕后若是输入make install,就能够把编译好的zlib库放在系统路径里,之后写代码就能够直接调用zlib提供的库函数了。
以上这些操做信息是写在源码目录下的readme文件里的,这里截取一段,.net

还有讲example的,告诉咱们example源码在哪。3d

源码目录下还有个INDEX文件,里面叙述了构成zlib的全部public header files和private source files,有了这些信息,就能够很方便的把须要的源码集成到本身的工程中去。blog

能够看出做者的文档写的很是好。接口

minizip

下面就来解决以前说的问题:解压缩多个文件(基于minizip)。
minizip源码目录在zlib-1.2.11/contrib目录下,进入这个目录,先看下该目录下的README.contrib文件,这个文件描述了基于zlib写的的第三方contributions,找到minizip

有个Makefile,打开以下,

内容比较简单,就是编译出2个elf文件:miniunz和minizip。经过名字就能够知道一个是用来解压,另外一个用来压缩。
其中,

  • 生成miniunz须要用到miniunz.c,unzip.c,ioapi.c和以前编译zlib时生成的静态库libz.a
  • 生成minizip须要用到minizip.c,zip.c,ioapi.c和以前编译zlib时生成的静态库libz.a

输入make执行Makefile,会有几个warning,

定位到miniunz.c的100行, 

这种条件编译写法是比较老的,如今编译器已经不提倡这种写法了,因此改成以下,

再编译就没这个warning了,按照这种方法也能够消除minizip.c中97行的warning。最后还剩个mkdir未声明,通常这是由于没有对应的头文件致使的,在终端输入man 2 mkdir并回车,

能够看出mkdir对应的是2个头文件,把这2个头文件添加到miniunz.c里,再次编译,就没有任何warning了。

编译完成后,就能够在minizip目录下看到2个elf文件:miniunz和minizip。这里先测试一下minizip,在终端输入./minizip -h并回车,获得如下帮助信息,

咱们在minizip目录下新建一个目录test,而后把minizip拷贝进去,而后在test目录下建2个文件a.txt和b.txt,随意写点内容在里面。

而后按照以前的帮助信息,输入./minizip -o -9 target.zip a.txt b.txt 并回车,能够发现生成了target.zip文件,打开它发现实现了多个文件的压缩,

再来测试下miniunz,先把a.txt和b.txt删除,再把miniunz拷贝进来。先看下miniunz的帮助信息,输入./miniunz -h并回车,结果竟然有error,说明这个miniunz.c里的main函数写的不够好,没有对-h的支持,毕竟是第三方contributions

不过不要紧,通常来讲-h不行,那么就直接./miniunz回车,此次帮助信息出来了,

咱们输入./miniunz -x target.zip,提示解压成功,咱们看下目录,确实OK了。

加密解压缩


解压缩多个文件已经测试OK,下面就来测试如下加密解压缩多个文件,毕竟minizip和miniunz的帮助信息里显示是支持加密的。
先测试minizip的加密功能,终端下输入./minizip -o -9 -p 123 target_crypt.zip 1.txt 2.txt并回车,能够看到生成了target_crypt.zip文件,双击打开它,提示须要输入密码,

咱们输入123,发现能够正确打开,说明加密功能没问题。

下面测试一下miniunz的解密功能(先把a.txt和b.txt删除),终端输入./miniunz -x -p 123 targer_crypt.zip并回车,发现居然没法解密,

根据提示,是unzOpenCurrentFilePassword()函数返回了-102,咱们去找一下unzOpenCurrentFilePassword()的定义,回到minizip目录下使用grep去查找,

发现该函数定义在unzip.c里,打开unzip.c找到这个函数,

函数开始处就有个可能返回的值UNZ_PARAMERROR,再用grep查下这个宏定义,

发现这个值就是-102,看来函数运行到这个return语句了。再看下代码,能够推断出NOUNCRYPT被定义了,而这个宏从字面感受是没有密码的意思,难道miniunz的工程屏蔽了解密功能?咱们再用grep查下NOUNCRYPT,看下在哪里设置的,

能够看出是在unzip.c里定义的宏,进去查看下,

果真是定义了NOUNCRYPT,把解密功能屏蔽了。既然找到了问题的根源,那么解密失败的问题就迎刃而解了:把这三行语句屏蔽掉,而后从新编译,从新生成miniunz,并拷贝到test目录下。再次输入./miniunz -x -p 123 target_crypt.zip并回车,就能够了。

看来这个miniunz仍是有点小bug的,不过仔细研究下也很容易解决。

总结
minizip能够达到解压缩多个文件的要求,并且其源码也比较少,结构也简单清晰,能够很方便地集成到本身的工程中来,或者本身修改,这就须要本身去研究下源码了。
若是想偷懒的话,能够只看minizip.c和miniunz.c里的main函数,把它改为一个接口函数,来达到本身的需求。

若是有写的不对的地方,但愿能留言指正,谢谢阅读。

相关文章
相关标签/搜索