2012-10-08 28 views
1

我試圖用VC++ 2010使用zlib-1.2.7來壓縮和膨脹一個文本文件。 我使用pipe.c作爲基礎,並重寫了main()以設置輸入/輸出文件。zlib deflate越來越Z_DATA_ERROR

我可以減壓任何文本文件,但我不能在沒有得到Z_DATA_ERROR(-3)的情況下膨脹大文件。

inf()def()不會從pipe.c改變。

這裏是我的main()

int main(){ 
    FILE *a, *b, *c; 
    int ret; 

    //ZIP 
    a = fopen("a_data.txt", "r"); 
    b = fopen("b_compressedData.zip", "w"); 
    if(a != NULL && b != NULL){ 
     ret = def(a, b, Z_DEFAULT_COMPRESSION); 
     printf("%d\n", ret); 

     if (ret != Z_OK) zerr(ret); 

     fclose(a); 
     fclose(b); 
    } 
    //UNZIP 
    b = fopen("b_compressedData.zip", "r"); 
    c = fopen("c_uncompressedData.txt", "w"); 
    if(c != NULL && b != NULL){ 
     ret = inf(b, c); 
     printf("%d\n", ret); 
     if (ret != Z_OK) zerr(ret); 

     fclose(b); 
     fclose(c); 
    } 

    return 0; 
} 

這裏是inf()功能:

int inf(FILE *source, FILE *dest) 
{ 
    int ret; 
    unsigned have; 
    z_stream strm; 
    unsigned char in[CHUNK]; 
    unsigned char out[CHUNK]; 

    /* allocate inflate state */ 
    strm.zalloc = Z_NULL; 
    strm.zfree = Z_NULL; 
    strm.opaque = Z_NULL; 
    strm.avail_in = 0; 
    strm.next_in = Z_NULL; 
    ret = inflateInit(&strm); 
    if (ret != Z_OK) 
     return ret; 

    /* decompress until deflate stream ends or end of file */ 
    do { 
     strm.avail_in = fread(in, 1, CHUNK, source); 
     if (ferror(source)) { 
      (void)inflateEnd(&strm); 
      return Z_ERRNO; 
     } 
     if (strm.avail_in == 0) 
      break; 
     strm.next_in = in; 

     /* run inflate() on input until output buffer not full */ 
     do { 
      strm.avail_out = CHUNK; 
      strm.next_out = out; 
      ret = inflate(&strm, Z_NO_FLUSH); 
      assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 
      switch (ret) { 
      case Z_NEED_DICT: 
       ret = Z_DATA_ERROR;  /* and fall through */ 
      case Z_DATA_ERROR: 
      case Z_MEM_ERROR: 
       (void)inflateEnd(&strm); 
       return ret; 
      } 
      have = CHUNK - strm.avail_out; 
      if (fwrite(out, 1, have, dest) != have || ferror(dest)) { 
       (void)inflateEnd(&strm); 
       return Z_ERRNO; 
      } 
     } while (strm.avail_out == 0); 

     /* done when inflate() says it's done */ 
    } while (ret != Z_STREAM_END); 

    /* clean up and return */ 
    (void)inflateEnd(&strm); 
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 
} 

回答

2

您需要的模式添加"b"fopen(),其中b是二進制。例如。 "rb""wb"。否則,在Windows上,您會遇到會導致二進制數據混亂的行尾轉換。

順便說一下,您不應該調用壓縮文件.zip,因爲它不是。 zlib寫入zlib格式的數據,或者請求gzip格式的數據。 zlib自己不寫zip格式的數據。有用於編寫zip文件的第三方代碼,例如在zlib源代碼分發的contrib目錄中,或者在libzip中。

我使用.zz作爲zlib格式數據的後綴。 .gz是gzip格式數據的後綴。

+0

謝謝馬克,它工作!我也會按照你對文件命名的建議。 – Tuxicoman