在C中放气和膨胀(zlib.h)

我正在尝试实现zlib.h deflate和inflate函数来压缩和解压缩char数组(不是文件)。

我想知道以下语法是否正确? 我错过了什么或定义错误的东西?

char a[50] = "Hello World!"; char b[50]; char c[50]; // deflate // zlib struct z_stream defstream; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; defstream.opaque = Z_NULL; defstream.avail_in = (uInt)sizeof(a); // size of input defstream.next_in = (Bytef *)a; // input char array defstream.avail_out = (uInt)sizeof(b); // size of output defstream.next_out = (Bytef *)b; // output char array deflateInit(&defstream, Z_DEFAULT_COMPRESSION); deflate(&defstream, Z_FINISH); deflateEnd(&defstream); printf("Deflate:\n%lu\n%s\n", strlen(b), b); // inflate // zlib struct z_stream infstream; infstream.zalloc = Z_NULL; infstream.zfree = Z_NULL; infstream.opaque = Z_NULL; infstream.avail_in = (uInt)sizeof(b); // size of input infstream.next_in = (Bytef *)b; // input char array infstream.avail_out = (uInt)sizeof(c); // size of output infstream.next_out = (Bytef *)c; // output char array inflateInit(&infstream); inflate(&infstream, Z_NO_FLUSH); inflateEnd(&infstream); printf("Inflate:\n%lu\n%s\n", strlen(c), c); 

你不能像这样打印缩小的输出。 它不是空终止。 你也不能纠结它。

由于您的输入是一个字符串,但您可能只希望传递包含空终止符的字符串内容。 所以将avail_in设置为strlen(a)+ 1。

在调用deflate之后,需要检查next_out和avail_out字段,以查看有多少数据写入输出缓冲区。

请参阅deflate调用下的文档。

这是你修改过的代码。 请注意,如果您正在压缩不是字符串的内容,则需要更改此字符串,并且还可以使用字符串进行压缩而不使用终止零并在解压缩后将其添加回来。

 char a[50] = "Hello World!"; char b[50]; char c[50]; // deflate // zlib struct z_stream defstream; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; defstream.opaque = Z_NULL; defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator defstream.next_in = (Bytef *)a; // input char array defstream.avail_out = (uInt)sizeof(b); // size of output defstream.next_out = (Bytef *)b; // output char array deflateInit(&defstream, Z_DEFAULT_COMPRESSION); deflate(&defstream, Z_FINISH); deflateEnd(&defstream); // This is one way of getting the size of the output printf("Deflated size is: %lu\n", (char*)defstream.next_out - b); // inflate // zlib struct z_stream infstream; infstream.zalloc = Z_NULL; infstream.zfree = Z_NULL; infstream.opaque = Z_NULL; infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input infstream.next_in = (Bytef *)b; // input char array infstream.avail_out = (uInt)sizeof(c); // size of output infstream.next_out = (Bytef *)c; // output char array inflateInit(&infstream); inflate(&infstream, Z_NO_FLUSH); inflateEnd(&infstream); printf("Inflate:\n%lu\n%s\n", strlen(c), c); 

zlib已经有一个简单的膨胀/放气function,你可以使用。

 char a[50] = "Hello, world!"; char b[50]; char c[50]; uLong ucompSize = strlen(a)+1; // "Hello, world!" + NULL delimiter. uLong compSize = compressBound(ucompSize); // Deflate compress((Bytef *)b, &compSize, (Bytef *)a, ucompSize); // Inflate uncompress((Bytef *)c, &ucompSize, (Bytef *)b, compSize); 

如有疑问,请查看zlib手册 。 我的代码很糟糕,抱歉= /

zpipe示例(http://zlib.net/zpipe.c)几乎涵盖了它,只需删除文件操作(带有前缀的函数),然后使用内存缓冲区替换inout ,尽管它可能是足以根据您的使用情况仅替换或保留缓冲区。 请注意,如果您计划使用未知大小的块,则需要调整缓冲区的大小,以便对任意大小的数据进行解压缩