2016-09-18 7 views
1

解凍にzlibを使用しようとしています。 Im zlibサイトのチュートリアルを見て、コードを膨張させると、異なるサイズの出力が生成されます。zlib異なる解凍サイズ

int CZLib::Inflate() { 
    int ret; 
    unsigned int have; 
    z_stream zstream; 
    unsigned char in[CHUNK]; 
    unsigned char out[CHUNK]; 

    zstream.zalloc = Z_NULL; 
    zstream.zfree = Z_NULL; 
    zstream.opaque = Z_NULL; 
    zstream.avail_in = 0; 
    zstream.next_in = Z_NULL; 
    ret = inflateInit(&zstream); 
    if (ret != Z_OK) 
     return ret; 

    do { 
     zstream.avail_in = fread(in, 1, CHUNK, fin); 
     if (ferror(fin)) { 
      (void)inflateEnd(&zstream); 
      return Z_ERRNO; 
     } 
     if (zstream.avail_in == 0) break; 
     zstream.next_in = in; 

     do { 
      zstream.avail_out = CHUNK; 
      zstream.next_out = out; 
      ret = inflate(&zstream, Z_NO_FLUSH); 
      assert(ret != Z_STREAM_ERROR); 
      switch (ret) { 
       case Z_NEED_DICT: 
        ret = Z_DATA_ERROR; 
       case Z_DATA_ERROR: 
       case Z_MEM_ERROR: 
        (void)inflateEnd(&zstream); 
        return ret; 
      } 
      have = CHUNK - zstream.avail_out; 
      if (fwrite(out, 1, have, fout) != have || ferror(fout)) { 
       (void)inflateEnd(&zstream); 
       return Z_ERRNO; 
      } 

     } while (zstream.avail_out == 0); 
    } while (ret != Z_STREAM_END); 

    (void)inflateEnd(&zstream); 
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 
} 

およびその他の

int CZLib::Inflate(const std::string& src) { 
    std::vector<char> output; 

    z_stream zstream; 
    zstream.zalloc = Z_NULL; 
    zstream.zfree = Z_NULL; 
    zstream.opaque = Z_NULL; 
    zstream.avail_in = 0; 
    zstream.next_in = Z_NULL; 

    int ret = inflateInit(&zstream); 
    if (ret != Z_OK) 
     return ret; 

    unsigned char in[CHUNK]; 
    unsigned char out[CHUNK]; 

    int have = 0, nByte = CHUNK, off = 0, remaining = src.size(); 

    if (src.size() < CHUNK) nByte = src.size(); 
    do { 
     memcpy(in, &src[off], nByte); 
     off += nByte; 
     remaining -= nByte; 

     if (nByte > 0) zstream.avail_in = nByte; 

     if (remaining > CHUNK) { nByte = CHUNK; } 
     else { nByte = remaining; } 

     if (zstream.avail_in == 0) break; 
     zstream.next_in = in; 

     do { 
      zstream.avail_out = CHUNK; 
      zstream.next_out = out; 

      ret = inflate(&zstream, Z_NO_FLUSH); 
      have = CHUNK - zstream.avail_out; 
      output.insert(output.end(), out, out + have); 

     } while (zstream.avail_out == 0); 
    } while (ret != Z_STREAM_END); 

    CFile* file = new CFile("in.out", "wb"); 
    file->Write<char>(&output[0], output.size()); 
    delete file; 
    return ret; 
} 

ITSは、同じデータを使用しています。それらのうちの1人は、ディスク上のファイルを読み取り、他は、メモリ(バッファ方法)を使用します。 CHUNKサイズ16384。最初のコードは524288(0x80000)と他の524800(0x80200)バイトを生成します。違いは512バイトです。なぜそれが起こっているのですか?

答えて

0

最初のコード例では、あなたがこの行

zstream.avail_in = fread(in, 1, CHUNK, fin); 

を持っていると、あなたはループを停止する

if (zstream.avail_in == 0) break; 

を持っています。 2番目のコード例では、ループを停止するには、同じ行を

を持っていますが、このラインがあります。

if (nByte > 0) zstream.avail_in = nByte; 
     ^^^^^^^^^ 
     So you only assign to zstream.avail_in when nByte > 0 

    .... 
    .... 

    if (zstream.avail_in == 0) break; 
     ^^^^^^^^^^^^^^^^ 
     Consequently this will not be true when nByte is zero and the 
     code will not exit 

を代わりにこれを試してみてください:

zstream.avail_in = nByte; // Unconditional assignment 

    .... 

    if (zstream.avail_in <= 0) break; // Less or equal to zero 
+0

いいえ、それは解決しませんでした問題。私は2つのバージョンを並べてチェックしました。すべての変数値とサイク​​ル数は同じです。私は問題がストリームまたは何かだと思う。興味深いことに、私は関数でファイルを作成すると、同じ問題が続く。狂ってる。 – streamer

+0

2番目の例のあなたのロジックは間違っていますが、おそらく、あなたは 'inflate'の戻り値のために外側のループから抜け出すでしょう。それが重要かどうかわかりませんが、最初の例では 'inflateEnd'が呼び出されていますが、2番目の例ではそうではありません。 – 4386427

+0

あなたは2番目の例について正しくあります、ありがとうございます。私はこの問題を解決しました。この問題は、ファイルストリームを無効にすることに起因します。私はCスタイルのファイルシステムを使用しています。ファイルが正常に閉じられたときに問題が解決しました。関数を終了してデストラクタを呼び出すと、ファイルは不完全な書き込みを行います(512バイト) – streamer

関連する問題