我正在Windows平台上用C++编写程序。我想压缩存储在
在进行了以上两个更改之后,
char[]
数组中的一些数据,并将其输出到文件中,稍后我将上传该文件到Unix服务器,并希望可以通过gzip -d
进行解压缩。
经过大量研究,我选择了miniz。此外,我在这里找到了gzip文件格式。
以下是创建gzip文件的代码片段:(对不起,我没有放一些变量的定义;它们在其他地方定义)
unsigned long zsize;
zpkg[0] = 0x1F;
zpkg[1] = 0x8B;
zpkg[2] = 8;
zpkg[3] = 0;
zpkg[4] = 0;
zpkg[5] = 0;
zpkg[6] = 0;
zpkg[7] = 0;
zpkg[8] = 0;
zpkg[9] = 0xFF;
compress2(zpkg + 10, &zsize, pkg, pkgSize, MZ_DEFAULT_LEVEL);
int footerStart = (int)zsize + 10;
mz_ulong crc = mz_crc32(MZ_CRC32_INIT, zpkg + 10, zsize);
zpkg[footerStart] = crc & 0xFF;
zpkg[footerStart + 1] = (crc >> 8) & 0xFF;
zpkg[footerStart + 2] = (crc >> 16) & 0xFF;
zpkg[footerStart + 3] = (crc >> 24) & 0xFF;
zpkg[footerStart + 4] = pkgSize & 0xFF;
zpkg[footerStart + 5] = (pkgSize >> 8) & 0xFF;
zpkg[footerStart + 6] = (pkgSize >> 16) & 0xFF;
zpkg[footerStart + 7] = (pkgSize >> 24) & 0xFF;
之后只需将zpkg
数组输出到文件即可。但是这样做不起作用;当我使用gzip解压缩时,出现了以下错误消息:
gzip: data stream error
gzip: test.gz: uncompress failed
请问有没有人能指出我做错了什么?
感谢Mark Adler和Michael的帮助,我找到了一个可行的解决方案。
首先,像Mark指出的那样,我应该使miniz返回一个原始的deflate数据流。这可以通过将-MZ_DEFAULT_WINDOW_BITS
(注意减号)作为第四个参数传递给mz_deflateInit2()
来实现。查看miniz源代码,compress2()
函数最终调用mz_deflateInit2()
并传递MZ_DEFAULT_WINDOW_BITS
,这意味着添加zlib头和尾。因此,最简单的修复方法是在那里添加一个减号,这样我仍然可以使用compress2()
函数。(这对我有效,因为我只在一个地方调用此函数)
其次,就像Michael指出的那样,CRC码应该在未压缩的数据上计算。所以我像这样修复它:
mz_ulong crc = mz_crc32(MZ_CRC32_INIT, pkg, pkgSize);
在进行了以上两个更改之后,
gzip -d
不再出现错误提示。