C++语言怎么用zlib库来解压.ISO或.zip文件?

C++语言怎么用zlib库来解压.ISO或.zip文件?,第1张

下面是使用zlib库的压缩和解压缩演示代码:

#include <stdlib.h>

#include <stdio.h>

#include <zlib.h>

int main(int argc, char* argv[])

{

FILE* file

uLong flen

unsigned char* fbuf = NULL

uLong clen

unsigned char* cbuf = NULL

/* 通过命令行参数将srcfile文件数据压缩后存放到dstfile文件中 */

if(argc < 3)

{

printf("Usage: zcdemo srcfile dstfile\n")

return -1

}

if((file = fopen(argv[1], "rb")) == NULL)

{

printf("Can\'t open %s!\n", argv[1])

return -1

}

/* 装载源文件数据到缓冲区 */

fseek(file, 0L, SEEK_END)    /* 跳到文件末尾 */

flen = ftell(file)        /* 获取文件长度 */

fseek(file, 0L, SEEK_SET)

if((fbuf = (unsigned char*)malloc(sizeof(unsigned char) * flen)) == NULL)

{

printf("No enough memory!\n")

fclose(file)

return -1

}

fread(fbuf, sizeof(unsigned char), flen, file)

/* 压缩数据 */

clen = compressBound(flen)

if((cbuf = (unsigned char*)malloc(sizeof(unsigned char) * clen)) == NULL)

{

printf("No enough memory!\n")

fclose(file)

return -1

}

if(compress(cbuf, &clen, fbuf, flen) != Z_OK)

{

printf("Compress %s failed!\n", argv[1])

return -1

}

fclose(file)

if((file = fopen(argv[2], "wb")) == NULL)

{

printf("Can\'t create %s!\n", argv[2])

return -1

}

/* 保存压缩后的数据到目标文件 */

fwrite(&flen, sizeof(uLong), 1, file)    /* 写入源文件长度 */

fwrite(&clen, sizeof(uLong), 1, file)    /* 写入目标数据长度 */

fwrite(cbuf, sizeof(unsigned char), clen, file)

fclose(file)

free(fbuf)

free(cbuf)

return 0

}

压缩的本质就是去冗余,去除信息冗余,使用最短的编码保存最完整的数据信息。所以对于不同的场景,压缩采用的算法也因时制宜,比如视频和图片可以采用有损压缩,而文本数据采用无损压缩。压缩率又取决于信息的冗余度,也就是内容中重复的比例。那些均匀分布的随机字符串,压缩率会降到最低,即香农限

deflate是zip文件的默认算法。它更是一种数据流压缩算法。

LZ77压缩算法采用字典的方式进行压缩,是一种简单但是很高效的数据压缩算法。其方式就是把数据中一些可以组织成短语的字符加入字典。维护三个概念: 短语字典、滑动窗口、向前缓冲区

压缩的逆过程,通过解码标记和保持滑动窗口中的符号来更新解压数据。当解码字符被标记:将标记编码成字符拷贝到滑动窗口中,一步一步直到全部翻译完成

在流式传输中,不定长编码数据的解码想要保持唯一性,必须满足唯一可以码的条件。而异前缀码就是一种唯一可译码的候选,当然这样会增加编码的长度,却可以简化解码。

huffman编码是一种基于概率分布的贪心策略最优前缀码。huffman编码可以有效的压缩数据,压缩率取决于数据本身的信息冗余度

计算数据中各符号出现的概率,根据概率从小到大,从下往上反向构建构造码树,这样最终得到的编码的平均长度是最短的。同时也是唯一可译的

解读:在一开始,每一个字符已经按照出现概率的大小排好顺序,在后续的步骤中,每一次将概率最低的两棵树合并,然后用合并后的结果再次排序(为了找出最小的两棵树)。在gzip源码中并没有专门去排序,而是使用专门的数据结构(比如最小堆或者红黑树)。

使用优先队列实现huffman树,最后基于Huffman树最终实现文件压缩。

具体步骤:

gzip = gzip 头 + deflate 编码的实际内容 + gzip 尾

zlib = zlib 头 + deflate 编码的实际内容 + zlib 尾

压缩之前:初始化各种输入输出缓冲区;

压缩:我们可以不断往这些缓冲区中填充内容,然后由deflate函数进行压缩或者indeflate函数进行解压

总结:在调用deflate函数之前,应用程序必须保证至少一个动作被执行(avail_in或者avail_out被设置),用提供更多数据或者消耗更多的数据的方式。avail_out在函数调用之前千万不能为零。应用程序可以随时消耗被压缩的输出数据

1 准备工作。

下载zlib.dll。以及相关头文件。将dll文件及头文件加入工程。

2 压缩:

调用函数compress.

形式为

int compress(Byte * dest, uLong* destLen, const Byte *source, ULONG sourceLen)

功能是将source指向的空间,长度为sourceLen的数据进行压缩,压缩数据储存在dest中,长度由参数destLen返回。

如果压缩出错,返回对应错误号,否则返回0.

3解压缩:

调用函数uncompress.

形式为

int uncompress(Byte * dest, uLong* destLen, const Byte *source, ULONG sourceLen)

功能是将source指向的空间,长度为sourceLen的数据进行解压缩,解压缩后的数据储存在dest中,长度由参数destLen返回。

如果解压缩出错,返回对应错误号,否则返回0.


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12039004.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存