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

Jan*_*son 9 c compression zlib deflate

我正在尝试实现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);
Run Code Online (Sandbox Code Playgroud)

Yeh*_*fez 26

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);
Run Code Online (Sandbox Code Playgroud)

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

  • 这个实用程序方法的问题是你需要以某种方式知道未压缩内容的大小......:/ (3认同)
  • 或许+1蹩脚,但它指向一个令人头脑麻木的解决方案,这是首选.`compress()`和`uncompress()`是关于你可以得到的最简单的形式,你提供的不仅仅是充分的. (2认同)

Guy*_*ton 7

你不能像这样打印缩小的输出.它不是空终止.你也不能搞砸它.

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

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

见文档这里放气号召下.

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

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);
Run Code Online (Sandbox Code Playgroud)