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库的uncompress函数可以解压缩一个内存中的压缩数据,如果要解压缩一个文件,可以先将文件中的数据读入到内存中,然后再调用uncompress函数进行解压缩。 以下是一个使用zlib解压缩文件的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <zlib.h> #define CHUNK_SIZE 1024 int main(int argc, char* argv[]) { if (argc != 3) { fprintf(stderr, "Usage: %s <compressed file> <output file>\n", argv[0]); return 1; } const char* compressed_file = argv[1]; const char* output_file = argv[2]; // 打开压缩文件 FILE* fp = fopen(compressed_file, "rb"); if (!fp) { fprintf(stderr, "Failed to open file: %s\n", compressed_file); return 1; } // 获取压缩文件大小 fseek(fp, 0, SEEK_END); size_t compressed_size = ftell(fp); fseek(fp, 0, SEEK_SET); // 分配缓冲区 char* compressed_data = (char*)malloc(compressed_size); if (!compressed_data) { fprintf(stderr, "Failed to allocate memory\n"); fclose(fp); return 1; } // 读取压缩文件数据 size_t read_size = fread(compressed_data, 1, compressed_size, fp); fclose(fp); if (read_size != compressed_size) { fprintf(stderr, "Failed to read file: %s\n", compressed_file); free(compressed_data); return 1; } // 创建输出文件 fp = fopen(output_file, "wb"); if (!fp) { fprintf(stderr, "Failed to create file: %s\n", output_file); free(compressed_data); return 1; } // 解压数据 char out[CHUNK_SIZE]; z_stream strm = { 0 }; strm.avail_in = compressed_size; strm.next_in = (Bytef*)compressed_data; strm.avail_out = CHUNK_SIZE; strm.next_out = (Bytef*)out; inflateInit(&strm); int ret = Z_OK; while (ret == Z_OK) { ret = inflate(&strm, Z_NO_FLUSH); if (ret == Z_STREAM_ERROR) { fprintf(stderr, "Failed to decompress data\n"); inflateEnd(&strm); fclose(fp); free(compressed_data); return 1; } if (strm.avail_out == 0) { fwrite(out, 1, CHUNK_SIZE, fp); strm.avail_out = CHUNK_SIZE; strm.next_out = (Bytef*)out; } } if (ret == Z_STREAM_END) { fwrite(out, 1, CHUNK_SIZE - strm.avail_out, fp); } inflateEnd(&strm); fclose(fp); free(compressed_data); printf("Decompression finished: %s -> %s\n", compressed_file, output_file); return 0; } ``` 这个示例程序会读取一个压缩文件,将文件中的数据解压缩后保存到另一个文件中。您需要在命令行中指定要解压缩的文件和输出文件的路径。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值