为char数组调整zlib-zpipe

adapt zlib zpipe for char arrays

本文关键字:zlib-zpipe 调整 数组 char      更新时间:2023-10-16

我有一个从.gz文件中获得的char数组(char*dataTo充气(,我想充气到另一个char数组中。

我不知道原始解压缩的大小,所以我相信这意味着我不能使用zlib库中的uncompress函数,因为根据手册:

未压缩数据的大小必须事先由压缩器保存,并通过此压缩库范围之外的某种机制传输到解压缩器。

我看过zpipe。C示例(https://zlib.net/zpipe.c),这里的inf函数看起来很合适,但我不确定如何将其从FILEs调整为char数组。

有人知道如何或有任何其他想法将一个char数组膨胀为另一个char阵列吗?

更新:

我在这里阅读:';zlib';返回Z_DATA_ERROR

对于通过gzip文件获得的数组,uncompress是不合适的。

我发现我可以使用gzopen、gzread和gzclose来完全解压缩文件,如下所示:

gzFile in_file_gz = gzopen(gz_char_array, "rb");
char unzip_buffer[8192];
int unzipped_bytes;
std::vector<char> unzipped_data;
while (true) {
unzipped_bytes = gzread(in_file_gz, unzip_buffer, 8192);
if (unzipped_bytes > 0) {
unzipped_data.insert(unzipped_data.end(), unzip_buffer, unzip_buffer + unzipped_bytes);
} else {
break;
}
}
gzclose(in_file_gz)

但我也希望能够解压缩char数组。我尝试了以下方法:

void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong *uncomprLen) {
int err;
z_stream d_stream; /* decompression stream */
d_stream.zalloc = NULL;
d_stream.zfree = NULL;
d_stream.opaque = NULL;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
err = inflateInit2(&d_stream, MAX_WBITS + 16);
CHECK_ERR(err, "inflateInit");
while (d_stream.total_out < *uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "inflate");
}
err = inflateEnd(&d_stream);
*uncomprLen = d_stream.total_out;
}

但在while循环中,膨胀方法在文件完全解压缩之前返回Z_STREAM_END。

该方法成功返回,但只写入了部分缓冲区。我在这里举了一个最低限度的工作示例:https://github.com/alanjtaylor/zlibExample

如果有人有时间看的话。

非常感谢!

您在github上的示例,"zippedFile.gz";是七个独立的gzip成员的串联。这是gzip标准(RFC 1952(允许的,zlibgz*文件函数会自动处理所有成员。

pigz将显示所有成员:

% pigz -lvt zippedFile.gz 
method    check    timestamp    compressed   original reduced  name
gzip 8  e323586d  ------ -----      616431    1543643   60.1%  zippedFile
gzip 8  7efd928a  ------ -----      369231     921600   59.9%  <...>
gzip 8  7ebd8b2a  ------ -----      919565    2319970   60.4%  <...>
gzip 8  3dd6e2ba  ------ -----      619670    1549236   60.0%  <...>
gzip 8  c1cb922e  ------ -----      600367    1533151   60.8%  <...>
gzip 8  a9fef06c  ------ -----      620250    1541785   59.8%  <...>
gzip 8  43b57506  ------ -----      623081    1555203   59.9%  <...>

inflate*函数一次只处理一个成员,以便使用Z_STREAM_END让您知道该成员已成功解压缩,并且CRC检查正常。

你所需要做的就是把你的充气机放在一个循环中,然后运行它,直到输入耗尽,或者你遇到错误。(这在zlib.h中inflateInit2的文档中有说明。(

你的充气机有一些问题,但我知道这只是让事情运转起来的初步尝试,所以我不会发表评论。

uncompress确实是为您准备好所有信息而设计的。这是一个实用函数。

可能包装inflate,这正是您想要使用的。你必须在一个循环中运行它,并管理";流";通过重复指向下一个缓冲数据块来参数化自己,直到它全部被吃掉。

文档中有一个带注释的示例。