我正在尝试实现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);
答案 0 :(得分:25)
zlib已经有了一个简单的膨胀/收缩功能。
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 manual。 我的代码很糟糕,抱歉= /
答案 1 :(得分:7)
你不能像这样打印缩小的输出。它不是空终止。你也不能纠结它。
由于您的输入是一个字符串,但您可能只希望传递包含空终止符的字符串内容。所以将avail_in设置为strlen(a)+ 1。
在调用deflate后,您需要检查next_out和avail_out字段,以查看有多少数据写入输出缓冲区。
请参阅deflate调用下的文档here。
这是您修改后的代码。请注意,如果您正在压缩不是字符串的内容,则需要更改此字符串以及字符串,您可以在没有终止零的情况下进行压缩,并在解压缩后将其添加回来。
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);
答案 2 :(得分:2)
zpipe示例(http://zlib.net/zpipe.c)几乎涵盖了它,只需删除文件操作(带有前缀的函数),然后替换in
和out
使用内存缓冲区,尽管根据您的使用情况,仅替换in
或保持缓冲区可能就足够了。请注意,如果您计划使用未知大小的块,则需要调整 out 缓冲区的大小以解决任意大小的数据