您的位置:首页 > 其它

zip 库 工作总结

2016-11-30 15:56 986 查看
最近在给项目加一些压缩和解压缩的工作。其中收录了一些 比较好的网址:

1.gzip,zip,zlib,7z,tar介绍
http://blog.csdn.net/lanmenghcc/article/details/40071923

2.zip压缩算法介绍
http://blog.csdn.net/a237443534/article/details/39857543

2.ziplib库 地址
https://nih.at/libzip/

3.zip结构 网址
http://blog.sina.com.cn/s/blog_4c3591bd0100zzm6.html

正文:由于项目中已经有了 zlib库(1.1.3)版本,所以 一开始准备 使用 这个库做一些解压缩的工作。后来发现 这个版本的 库 只 支持内存压缩,compress 和 uncompress函数,而且 压缩 格式 还是 gzip 。linux 中 常见的 压缩格式 .ta.gz 中的 gz 指的 就是 这个格式。ta 是 打包功能,gz 和 压缩功能,必须 两个程序 一起使用 才可以 压缩 文件夹 和 解压缩 文件夹。zip格式 是打包 和 压缩
都支持的。

后来了解到有ziplib库支持 zip压缩 和 解压缩,不过 后来 没有 使用这个库。(ps:由于 领导 不让用,呵呵,就是这么霸气)。

后来 又下载了最新的 zlib库,通过 minizip模块 来进行 zip压缩 和 解压缩。

这个是网盘的地址,包括了zlib1.2.8版本,ziplib1.1.3版本和一个 minizip的测试代码。

https://pan.baidu.com/s/1geKuTnt

获取解压缩的代码:

ZEXTRACT_API int GetFileInZip(CMemBuffer& buffer, const char* zfn, const char* fname, const char* password)
{
unzFile uf = unzOpen(zfn);

if (NULL == uf)
{
printf("unzOpen failed...\n");
return -1;
}

int err = unzLocateFile(uf, fname, 0);
if (UNZ_OK != err)
{
printf("GetFileInZip unzLocateFile failed... error:%d\n");
return err;
}

unz_file_info file_info;
char filename_inzip[256];

err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);

if (UNZ_OK != err)
{
printf("unzGetCurrentFileInfo failed... error:%d\n", err);
return err;
}

err = unzOpenCurrentFilePassword(uf, password);

if (UNZ_OK != err)
{
printf("unzOpenCurrentFilePassword failed... error:%d\n", err);
return err;
}

char* pBuff = new char[file_info.uncompressed_size];

if (pBuff == NULL)
{
unzCloseCurrentFile(uf);
unzClose(uf);
return -2;
}

err = unzReadCurrentFile(uf, pBuff, file_info.uncompressed_size);

if (err < 0)
{
printf("unzReadCurrentFile failed... error:%d\n", err);
delete [] pBuff;
unzCloseCurrentFile(uf);
unzClose(uf);
return err;
}
// Append data to the MemBuffer
buffer.Append(pBuff, file_info.uncompressed_size);

unzCloseCurrentFile(uf);

unzClose(uf);
return err;
}


代码分析:(其中解压缩核心算法 infalte()没做详细解释.)
 (unzip.c)unzOpen

------> unzOpenInternal

---------->初始化io api(ioapi.c) fill_fopen64_fillfunc

---------->打开zip文件, ZOPEN64

---------->寻找64位目录结束标志0x504b0607, unz64local_SearchCentralDir64,未找到进入下面的流程

---------->寻找目录结尾的标志0x504b0506,(unz64local_searchCentralDir函数),获取:核心目录的大小,起始位置,以及目录的数量。

---------->unzGoToFirstFile(unzip.c),查找第一个核心目录的信息。

-------------->unz64local_GetCurrentFileInfoInternal

------------------>定位到核心目录的位置,判断核心目录标志0x504b0102,读取核心目录的信息,包括压缩文件内容的起始位置,版本号,压缩所需版本号,修改时间,压缩方法,压缩前后的大小,crc,目录名和文件名以及他们的大小。

unzlocateFile(unzip.c) 查找文件的位置

------>unzGoToFirstFile(查找核心目录的信息,同上)

------>unzGetCurrentFileInfo64

---------->unz64local_GetCurrentFileInfoInternal,获取文件名,扩展名

---------->unzStringFileNameCompare,比较文件名和需要查找的文件名

---------->没有找到匹配的,unzGoToNextFile,然后跳到unz64local_GetCurrentFileInfoInternal,继续查找

unzGetCurrentFileInfo(unzip.c,获取当前文件信息)

------>unz64local_GetCurrentFileInfoInternal,获取文件信息

------>设置 获取信息

unzOpenCurrentFile(unzip.c,打开当前文件信息)

------>unzOpenCurrentFile3

---------->unz64local_checkCurrentFileCoherencyHeader

-------------->定位到查找文件头的位置(offset_curfile,unz64local_GetCurrentFileInfoInternal函数里设置的)

-------------->获取文件头的信息,包括压缩方法,名字扩展名,以及他们的大小等信息。比较文件头标志0x504b0304

-------------->输出文件头的压缩数据起始位置,以及文件的名字大小。

--------inflateInit2,解压缩初始化,自己也没看懂

---------->inflateReset2

-------------->inflateReset

-------------->infalteResetKeep

unzReadCurrentFile(unzip.c,读取文件压缩数据,并且解压缩,获取压缩之前的内容)pfile_in_zip_read

------>定位文件位置 ZSEEK64

------>读取文件内容ZREAD64

------>解压缩读取内容inflate(infalte.c),核心功能

---------->根据Inflate数据格式编码

---------->获取数据首位

---------->获取2,3位,得知:不使用Huffman编码(0),静态huffman编码(1),动态huffman编码(2)

------>crc检验

------>未到压缩数据末尾,循环定位文件位置ZSEEK64.

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: