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

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

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

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

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

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

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

还有讲example的,告诉我们example源码在哪。

源码目录下还有个INDEX文件,里面叙述了构成zlib的所有public header files和private source files,有了这些信息,就可以很方便的把需要的源码集成到自己的工程中去。

可以看出作者的文档写的非常好。

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函数,把它改成一个接口函数,来达到自己的需求。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

【转】使用minizip解压缩多个文件(基于zlib)的更多相关文章

  1. minizip -基于zlib开源代码库

    转载:https://www.topomel.com/archives/979.html 一.minizip 是一套用来压缩和解压文件的工具,其基于zlib开源代码库. 开源代码下载链接:http:/ ...

  2. javaCV开发详解之3:收流器实现,录制流媒体服务器的rtsp/rtmp视频文件(基于javaCV-FFMPEG)

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

  3. 基于Zlib算法的流压缩、字符串压缩源码

    原文:基于Zlib算法的流压缩.字符串压缩源码 Zlib.net官方源码demo中提供了压缩文件的源码算法.处于项目研发的需要,我需要对内存流进行压缩,由于zlib.net并无相关文字帮助只能自己看源 ...

  4. 使用zzip和minizip解压缩文件

    #include <zzip/zzip.h> #include <zlib.h> #include <zip.h> #include <unzip.h> ...

  5. java压缩/解压缩zip格式文件

    因为项目要用到压缩.解压缩zip格式压缩包,只好自己封装一个,对于网上流行的中文乱码的问题,本文的解决方法是用apache的包代替jdk里的.基本上还是比较好用的. 废话少说,直接上代码. }     ...

  6. 网页播放音频、视频文件——基于web的html 5的音乐播放器(转载)

    文章转载自:开源中国社区 [http://www.oschina.net] 想通过手机客户端(支持 Android.iPhone 和 Windows Phone)访问开源中国:请点这里 HTML5 是 ...

  7. 用Winrar批量解压缩有密码文件方法,只需输入一次密码

    老王上传的文件多是RAR压缩格式的, 每个系列下载完,都20多集,解压缩的时候要一个一个的输入密码,太浪费时间. 1) 把下载的需要解压缩的文件统一放到一个文件夹下. 2) 启动winrar程序 (从 ...

  8. tar---打包,解压缩linux的文件和目录

    tar命令可以为linux的文件和目录创建档案.利用tar,可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件.tar最初被用来在磁带上创建档案,现在,用户可以在 ...

  9. Ubuntu解压缩rar格式文件

    解压缩rar文件时,出现问题 解决方法: sudo apt-get install unrar

随机推荐

  1. .NET控件名称缩写一览表 zz

    标准控件1 btn Button2 chk CheckBox3 ckl CheckedListBox4 cmb ComboBox5 dtp DateTimePicker6 lbl Label7 llb ...

  2. GBT 31000-2015 社会治安综合治理基础数据规范 数据项 编码

    动态掌握 各级 综治组织 和 队伍建设 情况. 对 综治组织建设和其他业务 进行 统计. -- 数据描述 包括 序号  数据项名称 数据项类型 数据项长度 是否必填 相关条文和标准 -- 综治机构 包 ...

  3. Java笔记(十一)通用容器类和总结

    通用容器类和总结 一.抽象容器类 一)AbstractCollection 提供了Collection接口的基础实现,具体来说,实现了如下方法: public boolean addAll(Colle ...

  4. git从其他分支提取文件merge到当前分支

    git checkout A -- [a.go b.go]将A分支中的a.go, b.go两文件合并到当前分支注意:会将当前分支的对应文件强行覆盖

  5. 谈一谈java里面的反射机制

    首先来看看百度百科中是如何定义的: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方 ...

  6. BZOJ3945 : 无聊的邮递员

    因为两个人方案的对称性,可以将$k$除以$2$,转化为在$n-1$个间隔中设置若干断点,求第$k$小的增量. 对于选中的相邻的断点$(a,a+1)$和$(b,b+1)$,增量为$|x_a-x_{b+1 ...

  7. [P1082][NOIP2012] 同余方程 (扩展欧几里得/乘法逆元)

    最近想学数论 刚好今天(初赛上午)智推了一个数论题 我屁颠屁颠地去学了乘法逆元 然后水掉了P3811 和 P2613 (zcy吊打集训队!)(逃 然后才开始做这题. 乘法逆元 乘法逆元的思路大致就是a ...

  8. 3ds max学习笔记(十四)-- (FFD自由变形)

    FFD长方体,FFD圆柱体:   栗子2:通过对长方体进行自由编辑,松弛,和涡轮平滑的操作实现抱枕模型,抱枕表面的凹凸效果,可以通过贴图的方式来实现:

  9. Java基础知识--泛型

    什么是泛型?为什么使用泛型? 泛型,就是参数化类型.提到参数,最熟悉的就是定义方法时候的形参,然后调用此方法时传递实参.顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也 ...

  10. Disruptor 详解

    想了解一个项目,最好的办法就是,把它的源码搞到本地自己捣鼓. 在网上看了 N 多人对 Disruptor 速度的吹捧,M 多人对它的机制分析,就连 Disruptor 官方文档中,也 NB 哄哄自诩: ...