【问题标题】:Uncompress() of 'zlib' returns Z_DATA_ERROR'zlib' 的 Uncompress() 返回 Z_DATA_ERROR
【发布时间】:2014-04-02 11:06:04
【问题描述】:

我做了一个简单的函数,它接受一个 gzip 压缩文件,然后提取到某个地方。出于测试目的,我使用了一个通过通用实用程序 gzip 压缩的文本文件。 但由于某种原因,Uncompress() 返回错误Z_DATA_ERROR

我进入调试器直到函数,它肯定得到正确的数据(整个文件内容,它只有 37 个字节),所以它似乎是两个之一:可怕的 zlib-bug 正在偷你的时间现在,或者我错过了一些重要的事情,然后我真的很抱歉。

#include <zlib.h>
#include <cstdio>

int UngzipFile(FILE* Dest, FILE* Source){
    #define IN_SIZE 256
    #define OUT_SIZE 2048
    bool EOFReached=false;
    Bytef in[IN_SIZE];
    Bytef out[OUT_SIZE];
    while(!EOFReached){//for no eof
        uLong In_ReadCnt = fread(in,1,IN_SIZE,Source);//read a bytes from a file to input buffer
        if(In_ReadCnt!=IN_SIZE){
            if(!feof(Source) ){
                perror("ERR");
                return 0;
            }
            else    EOFReached=true;
        }
        uLong OutReadCnt = OUT_SIZE;//upon exit 'uncompress' this will have actual uncompressed size
        int err = uncompress(out, &OutReadCnt, in, In_ReadCnt);//uncompress the bytes to output
        if(err!=Z_OK){
            printf("An error ocurred in GZIP, errcode is %i\n", err);
            return 0;
        }
        if(fwrite(out,1,OutReadCnt,Dest)!=OUT_SIZE ){//write to a 'Dest' file
            perror("ERR");
            return 0;
        }
    }
    return 1;
} 

int main(int argc, char** argv) {
    FILE* In = fopen("/tmp/Kawabunga.gz", "r+b");
    FILE* Out = fopen("/tmp/PureKawabunga", "w+b");
    if(!In || !Out){
        perror("");
        return 1;
    }
    if(!UngzipFile(Out,In))printf("An error encountered\n");
}

【问题讨论】:

  • uncompress() 是针对用 deflate 算法压缩的原始数据,它不知道 gzip 格式。
  • @nos 我也想过。现在我正在寻找一个标头规范,如果我找到了,我会在这里发布一个可行的解决方案。虽然我想知道:应该有些东西已经在工作了......
  • 您可以在链接到的页面上使用 gzopen() 函数。或者使用 inflate() 函数。 gzip 格式记录在 RFC 1952
  • 真的,gzopen() 允许读取文件,就像它是未压缩的文件一样。 @nos,如果您将两个 cmets 发布为答案,那就太好了,这就是解决方案!
  • 不,uncompress() 用于 zlib 格式,而不是原始 deflate。但是,是的,它不知道 gzip 格式。

标签: c++ gzip zlib


【解决方案1】:

您应该使用inflate(),而不是uncompress()。在inflateInit2() 中,您可以指定gzip 格式(或自动检测zlib 或gzip 格式)。请参阅 zlib.h 中的文档。

您可以在 zlib 中获取 uncompress() 的源代码,并进行简单的更改以使用 inflateInit2() 而不是 inflateInit() 来创建您自己的 gzipuncompress(),或者任何您喜欢的名称。

【讨论】:

  • 我在 inflate() 之前尝试过,但是 manual 太混乱了。最开始有写,那个zlibgzip格式是不一样的。但它也说,也支持 gzip,那么我应该在哪里指出应该使用哪种格式?函数和结构都没有这方面的东西。也许它可以做某种自动识别?那么我可以将哪个字符块最小化到 inflate() 函数中?这个人似乎不是人写的,他们希望有人试图触摸图书馆:D
  • 正如我所说,inflateInit2()。来自手册:“windowBits 也可以大于 15 用于可选的 gzip 解码。将 32 添加到 windowBits 以启用 zlib 和 gzip 解码并自动检测头,或添加 16 以仅解码 gzip 格式(zlib 格式将返回 Z_DATA_ERROR) 。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多