2014-04-02 312 views
1

我做了一个简单的函数,它需要一个gzip文件,并从某处提取。出于测试目的,我使用的文本文件已通过通用实用程序gzip gzip进行了gzip压缩。 但由于某种原因,Uncompress()返回错误Z_DATA_ERROR。我使用调试器直到函数,它肯定会得到正确的数据(整个文件的内容,它只有37个字节),所以它似乎是其中的一个:可怕的zlib-bug正在窃取你的时间现在,或者我失去了一些重要的东西,然后我真的很抱歉。'zlib'的解压缩()返回Z_DATA_ERROR

#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"); 
} 
+0

uncompress()是用deflate算法压缩的原始数据,它不知道gzip格式。 – nos

+0

@nos我也想过了。现在我正在寻找一个标题规范,如果我找到了,我会在这里发布一个工作解决方案。虽然我想知道:应该已经有工作了...... –

+1

您可以在链接到的页面上使用gzopen()函数。或者使用inflate()函数。 gzip格式在RFC 1952 – nos

回答

4

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

你可以把源代码uncompress()在zlib的和做一个简单的变化使用inflateInit2(),而不是inflateInit()创建自己的gzipuncompress(),或任何你想调用它。

+0

我试过_inflate()_之前,但它[手动](http://www.zlib.net/manual.html)太混乱。起初写道,_zlib_和_gzip_格式是不同的。但它也表示,gzip也支持,那么我应该在哪里指出应该使用哪种格式?功能和结构也没有关于此的任何事情。也许它可以做某种自动识别?那么哪个是最小的字符块可以扔到_inflate()_函数中?这个人似乎并不是人们写的,他们想要有人试图触摸这个图书馆:D –

+1

正如我所说的,用'inflateInit2()'。在手册中:“对于可选的gzip解码,”windowBits也可以大于15;对windowBits添加32以启用自动头部检测的zlib和gzip解码,或者添加16来仅解码gzip格式(zlib格式将返回Z_DATA_ERROR) “。 –