使用zlib解压标准zip文件
来源:互联网 发布:淘宝评论在哪里 编辑:程序博客网 时间:2024/04/28 16:39
zlib库可以解压zip压缩数据,但是在做标准zip文件解压的时候发现会出现问题,原因其实是因为zlib的压缩格式与标准zip的压缩格式有那么一点区别,最初这个问题让我很纠结,在经过实验后,我将标准zip压缩的文件与使用zlib库函数压缩的文件使用二进制编辑器打开时发现了它们的一点点区别,使用zlib库函数压缩后的数据与标准zip压缩后的数据相比在头部多了个0x9c78,(而且数据的尾部也稍有不同,这个我没有具体深入,因为我发现貌似影响不大的样子,目前没有遇到问题),所以在使用zlib函数解压标准zip压缩数据的时候我们可以将标准zip压缩的数据前面加上0x9c78再使用zlib库函数解压,这样就能顺利进行了
下面还有个问题,就是标准zip文件格式的文件,我们会发现一个zip文件里面会有很多的文件,那么我们如何知道一个zip文件里面有哪些具体内容呢?
标准zip文件的格式如下
压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志
在这个数据区中每一个压缩的源文件/目录都是一条记录,记录的格式如下:
[文件头+ 文件数据 + 数据描述符]
文件头
组成 长度
文件头标记 4 bytes (0x04034b50)
解压文件所需 pkware 版本 2 bytes
全局方式位标记 2 bytes
压缩方式 2 bytes
最后修改文件时间 2 bytes
最后修改文件日期 2 bytes
CRC-32校验 4 bytes
压缩后尺寸 4 bytes
未压缩尺寸 4 bytes
文件名长度 2 bytes
扩展记录长度 2 bytes
文件名 (不定长度)
扩展字段 (不定长度)
这样,我们可以先读出文件头,然后读出文件名,再读出扩展字段(如果有的话)
之后我们再读出压缩的数据,将这个数据头部加入0x9c78后使用zlib库函数解压
这时如果我们得到的压缩后的数据为0则表示这是个文件夹的名称,我们创建一个文件夹,如果不为0我们就创建一个文件
一直重复上面的操作,一直到文件末尾
还有一点要注意,如果你得到的压缩后的数据大小与压缩前的数据大小相同的话,那么这个文件应该是没有被压缩过的
这时你只需要直接将它读出来并写入文件即可
下面还有个问题,就是标准zip文件格式的文件,我们会发现一个zip文件里面会有很多的文件,那么我们如何知道一个zip文件里面有哪些具体内容呢?
标准zip文件的格式如下
压缩源文件数据区+压缩源文件目录区+压缩源文件目录结束标志
在这个数据区中每一个压缩的源文件/目录都是一条记录,记录的格式如下:
[文件头+ 文件数据 + 数据描述符]
文件头
组成 长度
文件头标记 4 bytes (0x04034b50)
解压文件所需 pkware 版本 2 bytes
全局方式位标记 2 bytes
压缩方式 2 bytes
最后修改文件时间 2 bytes
最后修改文件日期 2 bytes
CRC-32校验 4 bytes
压缩后尺寸 4 bytes
未压缩尺寸 4 bytes
文件名长度 2 bytes
扩展记录长度 2 bytes
文件名 (不定长度)
扩展字段 (不定长度)
这样,我们可以先读出文件头,然后读出文件名,再读出扩展字段(如果有的话)
之后我们再读出压缩的数据,将这个数据头部加入0x9c78后使用zlib库函数解压
这时如果我们得到的压缩后的数据为0则表示这是个文件夹的名称,我们创建一个文件夹,如果不为0我们就创建一个文件
一直重复上面的操作,一直到文件末尾
还有一点要注意,如果你得到的压缩后的数据大小与压缩前的数据大小相同的话,那么这个文件应该是没有被压缩过的
这时你只需要直接将它读出来并写入文件即可
由于这里我只是简单地想要解压文件,所以并没有读取和处理压缩源目录区,下面上一个代码
#include <stdlib.h>#include <stdio.h>#include <string.h>#include <zlib.h>#include <errno.h>struct data{ unsigned long head; unsigned short pk; unsigned short q; unsigned short type; unsigned short time; unsigned short date; unsigned long crc; unsigned long d_len; unsigned long len; unsigned short f_len; unsigned short e_len;}__attribute__((packed));void error_quit(const char *msg){ perror(msg); exit(-1);}void memcat(char *tmp,char *buf,unsigned long len){ int i=2,j=0; while(len) { tmp[i]=buf[j]; ++i; ++j; --len; }}int get_zip_file_num(char *zip_file){ int i=0; FILE *fp; struct data zip; if((fp=fopen(zip_file,"rb"))==NULL) return -1; while(!feof(fp)) { fread(&zip,sizeof(struct data),1,fp); if(zip.f_len <= 0) break; fseek(fp,zip.f_len,SEEK_CUR); if(zip.e_len > 0) fseek(fp,zip.e_len,SEEK_CUR); if(zip.d_len > 0) fseek(fp,zip.d_len,SEEK_CUR); ++i; } fclose(fp); return i;}void unzip(char *zip_file){ struct data zip; FILE *fp,*out; char *buf,*source,*name,*tmp; unsigned short s=0x9c78; unsigned long blen; if((fp=fopen(zip_file,"rb"))==NULL) error_quit("Open File"); while(!feof(fp)) { fread(&zip,sizeof(struct data),1,fp); if(zip.f_len <= 0) break; name=malloc(zip.f_len+1); bzero(name,zip.f_len+1); fread(name,zip.f_len,1,fp); if(zip.e_len > 0) fseek(fp,zip.e_len,SEEK_CUR); if(zip.d_len == 0) mkdir(name,0777); else if(zip.d_len == zip.len) { if((out=fopen(name,"w"))==NULL) error_quit("Create File"); printf("Unzip %s . . .\n",name); buf=malloc(zip.d_len+1); bzero(buf,zip.d_len+1); fread(buf,zip.d_len,1,fp); fwrite(buf,zip.d_len,1,out); fclose(out); free(buf); printf("Unzip %s Successed . . .\n",name); } else { buf=malloc(zip.d_len+1); bzero(buf,zip.d_len+1); fread(buf,zip.d_len,1,fp); source=malloc(zip.len+1); bzero(source,zip.len+1); tmp=malloc(zip.d_len+3); bzero(tmp,zip.d_len+3); memcpy(tmp,&s,sizeof(s)); memcat(tmp,buf,zip.d_len); if((out=fopen(name,"w"))==NULL) error_quit("Create File"); printf("Unzip %s . . .\n",name); blen=compressBound(zip.len); uncompress(source,&blen,tmp,zip.len); fwrite(source,zip.len,1,out); fclose(out); free(source); free(tmp); free(buf); printf("Unzip %s Successed . . .\n",name); } free(name); } fclose(fp);}int main(int argc,char **argv){ if(argc != 2) error_quit("Argument Error!"); printf("%d files in %s\n",get_zip_file_num(argv[1]),argv[1]); unzip(argv[1]); return 0;}
0 0
- 使用zlib解压标准zip文件
- zlib 解压zip文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用 ZLib 压缩/解压 ZIP 文件
- 使用zlib库解压*.zip文件
- [VC++]_[初级]_[使用zlib标准库解压zip文件]
- 使用zlib解压.apk/.zip文件(Windows&Ubuntu)
- [zlib]_[初级]_[使用Zlib完整解压zip内容]
- 使用zlib压缩/解压文件
- zlib minizip 实现解压zip
- 使用ZLib 压缩/解压缩 zip文件
- 心得 ~ 使用 zlib库 解压缩 zip文件
- [Zlib]_[初级]_[使用zlib库解压提取文件]
- 使用开源库zlib压缩和解压文件
- 使用开源库zlib压缩和解压文件
- 运行Fast R-CNN的代码
- OC教程10-NSNumber详细
- 那些年我还不懂:IEnumerable,IEnumerator
- 使用Nexus搭建Maven代理仓库
- Spring注解Annotion详解
- 使用zlib解压标准zip文件
- 怎么检查电路原理图
- 黑马程序员---jdk1.5的一些新特性
- 思贝克商城教您如何选择轴承润滑脂
- iOS AFNetworking下载文件
- 五十七 K歌之王 (第一部完结)
- VNC配置Linux远程桌面
- html/css编写规范
- NSProxy实现AOP方便为ios应用实现异常处理策略