我的问题是我的程序依赖于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流:
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,程序挂起的那一行。
在这个断点处,我可以看到变量zStreamflushZStreamFlag和其他变量的值。zStream变量不是NULL,我可以用print zStreamprint zStream.next_in等来验证,这些都是用我感兴趣的数据填充的。
如果我在next中键入gdb,那么这一行代码将被处理,整个进程将挂起,我将在这一行代码前后使用日志语句验证这一点显示“before”日志语句,但“after”语句不显示。
我的问题是:为什么deflate()挂在这里?我没有正确初始化输出流吗没有正确使用deflate()?我一直在想办法解决这个问题,但运气不好。谢谢你的建议。

最佳答案

函数应该将指针指向z_流,而不是将结构传入init函数正在初始化有效的本地副本,该副本将被丢弃然后压缩函数将有一个垃圾z_流传递给它。
例如:

int setupGzipOutputStream(z_stream *zStream) {
    int zError;
    zStream->zalloc = Z_NULL;
    ...
}

... etc.

您的压缩函数似乎没有考虑字符串末尾的空值,因此当您尝试重新膨胀数据时可能会出现问题。
zStream.avail_in = strlen(myData);

可能需要:
zStream.avail_in = strlen(myData) + 1;

关于c - 为什么zlib deflate()挂起?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13878917/

10-12 03:40