zlib uncompress解压数据inflate_fast函数出错的解决办法

转自:http://blog.csdn.net/u013283835/article/details/70311499

最近在开发pdf电子签章过程中遇到了点棘手的问题,因为pdf标准支持读取zlib压缩后的stream对象,因此,可以通过这个手段将stream里面的操作数据用zlib解压出来,以此来研究里面的具体操作是什么,但是当我们用二进制将stream里面的数据读到文件里面的时候,会出现一些很棘手的错误,导致了很多人怀疑这条路是走不通的,这里,楼主贡献一下自己的思路:

     问题1:读取完文件之后会自动出现,没错数据开头跟结尾会多加了0d0a也就是换行符,因为我们在用zlib解决的时候,会返回-3,也就是数据错误,解决方法就是将这4个字符删掉。

     问题2:当我们在调用uncompress解压数据的时候,很有可能会在inflate_fast这个函数里面崩溃掉,原因是内存读取失败,也就是越界了,并且出错的地方是一些汇编代码。这让你很费解,到底该怎么办,汇编代码不太好搞定。这时候很多人就会在这里停住,可能会想起他的出路了。而楼主并没有因此而停止脚步,下面让我们揭开神秘的面纱:

     首先我们打开inffast.c这个文件,拉到头,你会看到这样一行文字,如下,意思就是如果你用了汇编编译器来编译的话,那么很有可能汇编的代码有bug(坑。。。),而在zlib官网下载的zlib库默认的是定义了ASMINF这个库的,因此就出现了开头说的那个bug,问题到这里似乎就迎刃而解了,解决的方案就是将这个宏定义注释掉,也就是不使用汇编版的infate_fast函数,而是使用C语言版的,这样就不会出现问题了。一个人的开发,真是的很枯燥而且是考验心性的,我现在特别理解为什么公司招聘的时候都要先进行心理测试,问题一头雾水的时候,太考验各人心里的承受能力了,这几天快被这个折磨疯了


当使用zlib库中的inflate()函数进行解压缩时,返回Z_OK表示解压缩成功,但并不一定表示已经解压缩完所有数据。因为一次解压缩操作可能只解压缩出一部分数据,需要多次调用inflate()函数解压缩完所有数据。 在使用inflate()函数时,需要使用循环语句(例如while循环)来多次调用inflate()函数,直到解压缩出所有数据。在每次调用inflate()函数时,需要检查解压缩的返回值,如果返回值为Z_OK,说明解压缩成功,但并不一定表示已经解压缩完所有数据,需要继续调用inflate()函数解压缩下一部分数据。如果返回值为Z_STREAM_END,说明已经解压缩完所有数据,可以退出循环。 以下是一个示例代码: ```c++ #include <zlib.h> int main() { // 初始化zlibzlibVersion(); // 定义输入数据和输出数据 char input_data[1024] = {0}; char output_data[1024] = {0}; // 初始化解压器 z_stream stream; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; stream.avail_in = 0; stream.next_in = Z_NULL; inflateInit(&stream); // 循环解压数据 int ret = 0; while (true) { // 读取输入数据到缓冲区 // ... // 设置解压器输入数据 stream.avail_in = input_data_len; stream.next_in = (Bytef*)input_data; // 解压数据到输出缓冲区 stream.avail_out = sizeof(output_data); stream.next_out = (Bytef*)output_data; ret = inflate(&stream, Z_NO_FLUSH); // 处理解压返回值 if (ret == Z_STREAM_END) { // 已经解压缩完所有数据 break; } else if (ret != Z_OK) { // 解压出错 // ... break; } // 处理输出数据 // ... // 检查解压器是否已经解压缩完所有数据 if (stream.avail_in == 0) { break; } } // 结束解压inflateEnd(&stream); return 0; } ``` 需要注意的是,如果输入数据中包含多个zlib数据块(也就是多次调用deflate()函数压缩的数据),那么需要在每个数据块之间调用`inflateReset()`函数重置解压器状态。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值