我的问题是我的程序依赖于使用zlib的deflate()
函数。
我首先初始化我的z_stream
,如下所示:
int setupGzipOutputStream(z_stream zStream) {
int zError;
zStream.zalloc = Z_NULL;
zStream.zfree = Z_NULL;
zStream.opaque = Z_NULL;
zError = deflateInit(&zStream, Z_COMPRESSION_LEVEL);
/* error handling code to test if zError != Z_OK... */
return EXIT_SUCCESS;
}
我尝试使用以下函数将数据写入我的z-stream:
int compressDataToGzipOutputStream(unsigned char *myData, z_stream zStream, Boolean flushZStreamFlag) {
int zError;
int zOutHave;
FILE *outFp = stdout;
unsigned char zBuffer[Z_BUFFER_MAX_LENGTH] = {0};
zStream.next_in = myData;
zStream.avail_in = strlen(myData); /* myData is a null-terminated string */
do {
zStream.avail_out = Z_BUFFER_MAX_LENGTH;
zStream.next_out = zBuffer;
zError = deflate(&zStream, (flushZStreamFlag == kFalse) ? Z_NO_FLUSH : Z_FINISH);
/* error handling code to test if zError != Z_OK... */
zOutHave = Z_BUFFER_MAX_LENGTH - zStream.avail_out;
fwrite(zBuffer, sizeof(unsigned char), zOutHave, outFp);
fflush(outFp);
} while (zStream.avail_out == 0);
return EXIT_SUCCESS;
}
我将这两个函数(简化为了提出这个问题的目的)称为如下:
z_stream zOutStream;
setupGzipOutputStream(zOutStream);
compressDataToGzipOutputStream(data, zOutStream, kFalse);
compressDataToGzipOutputStream(data, zOutStream, kFalse);
...
compressDataToGzipOutputStream(data, zOutStream, kTrue);
然后我用zOutStream
分解deflateEnd()
结构。
上一个压缩步骤的kTrue
值会将Z_FINISH
标记发送到deflate()
,而不是Z_NO_FLUSH
。
它挂在以下一行:
zError = deflate(&zStream, (flushZStreamFlag == kFalse) ? Z_NO_FLUSH : Z_FINISH);
然后我尝试使用gdb
。我在这一行设置break
,这是程序挂起的行。
在此断点处,我可以看到变量zStream
,flushZStreamFlag
和其他变量的值。 zStream
变量不是NULL
,我可以使用print zStream
,print zStream.next_in
等验证这些变量,这些变量填充了我感兴趣的数据。
如果我在next
中键入gdb
,则会处理此行代码,并且整个过程会挂起,我会在此代码行之前和之后使用日志语句进行验证。显示“之前”日志语句,但“之后”语句不显示。
我的问题是:为什么deflate()
悬在这里?我没有正确初始化输出流吗?没有正确使用deflate()
?我一直在试图解决这个问题,但是没有运气。感谢您提出的任何建议。
答案 0 :(得分:5)
你的函数应该使用指向z_stream的指针,而不是传入结构。你的init函数初始化什么是有效的本地副本,它将被丢弃。然后你的压缩函数会传递一个垃圾z_stream。
e.g:
int setupGzipOutputStream(z_stream *zStream) {
int zError;
zStream->zalloc = Z_NULL;
...
}
... etc.
看起来您的压缩函数没有考虑字符串末尾的null,因此当您尝试重新膨胀数据时可能会导致问题。
zStream.avail_in = strlen(myData);
可能希望成为:
zStream.avail_in = strlen(myData) + 1;