Chinaunix首页 | 论坛 | 博客
  • 博客访问: 304948
  • 博文数量: 174
  • 博客积分: 3061
  • 博客等级: 中校
  • 技术积分: 1740
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-04 22:43
文章分类

全部博文(174)

文章存档

2011年(54)

2010年(14)

2009年(30)

2008年(26)

2007年(27)

2006年(23)

我的朋友

分类:

2007-01-30 09:37:13

今天由于工作需要,需要挑选一个能够进行线程安全的压缩库.
1. 能够机型基本的buffer压缩.
2. 能够进行递归方式的目录结构压缩.

经过挑选发现
1. zlib 是能够多线程安全的,但是它不能够进行目录结构压缩.
2. minizip / miniuzip 是线程安全的,但是它在压缩的时候不能够进行目录压缩,解压缩倒是可以的.
3. zip/unzip 是全能的,但是网站明确表示这个库不能够多线程使用.

下面是我的探索:
Q: zip为什么不支持多线程使用
A: zip的source code中大量使用了全局变量,作为函数间共享的方式,数量非常庞大。

Q: minizip 为什么无法进行目录压缩?
A: minizip 实际上阿可以压缩,不过代码开发者没有实现.

我是如何实现minizip进行目录压缩的.

下面是我的探索过程...

综合考虑,这些库都是可以商用的,最后考虑在minizip/miniuzip 基础上进行修改,增加目录项的压缩.

现象:
1. 我压缩了空文件1 , 空目录1 (用zip),发现实际上差别非常下,仅仅在entryname上有区别,前者1, 后者1\ .
2. miniuzip 在解压缩时候,实际上如果发现这是个目录名称,那么它会直接创建目录.

下面是对miniuzip 进行调试跟踪的观察.
一. 压缩了file.zip ,内部只有一个空文件1, 进行调试跟踪.
1.  打开压缩文件.
2. 查询centraldir信息从end of centraldir
  2.1.  获取文件大小.
  2.2.  如果文件大小小于MAX_COMMENTSIZE 那么直接读取整个文件,否则读取MAX_COMMENTSIZE。 
  2.3.  读取出readsize。
  2.4.  从读取出的buffer中来判断0x06054b50,找出这个end of centraldir位置.
  2.5.  调转到endcentralpos 读取signature code(0x06054b50)
  2.6.  读取卷数,entry数量,centraldir 大小/偏移量,comment_size 等.
  2.7.  centralendpos -(centraloffset + centraldirsize) , 来获取centraldir对于卷开头位置的偏移量,准备读取centraldir.
3. 读取centraldir信息
  3.1.  从offsetcentraldir开始读取signature(0x02014b50) .
  3.2.  读取出版本号,压缩方式,日期信息,CRC,压缩大小,未压缩大小,entryname大小,file_extra_size , size_comment_file,起始卷index,internal file attr., external file attr., 当前项对于centraldir 的offset.
4. 读取entryinternal信息,比如名称,offset
5. 读取local file header 信息
  5.1. 检查signature(0x04034b50) , 日期,协议中local header信息.

二. 内部空目录1, 进行调试跟踪
   实际上差别仅仅在entryname,entryname length,以及由此导致的结构offset.

三. zip 压缩过程实现
  对比zip在处理目录,文件都是1(空文件)的项时候实际上没有差别 ,却别仅仅是如果是目录那么最后一个字符必须是'\' or '/' ,而文件项则不是.


同上上面的测试发现,只要让minizip能够支持比如 minizip c:\1\ (c:\1\ 就可以了.
所以代码的修改在原来的代码基础上,当发现filenameinzip的最后字符是'\' or '/' 时候就放弃读取文件内容的代码,直接关闭即可.

Q : minizip如果支持目录的递归?
A: 如果用户输入了一个目录,那么minizip需要讲这个目录进行递归分解,比如 有个目录1 ,它下面有个文件叫做1234.txt 有一个目录叫做 123,而用户的输入是minizip -R c:\1 ,实际minizip内部执行了类似如下指令 minizip c:\1\ c:\1\1234.txt c:\1\123 过程就是这样,后续的继续包装完成目录递归即可.

  

阅读(4745) | 评论(1) | 转发(0) |
1

上一篇:cross compile libgcrypt

下一篇:regex 阅读!

给主人留下些什么吧!~~

chinaunix网友2011-01-09 15:47:44

作者还在吗?请问zip/unzip指的是Info-Zip吗?