2016-09-19 57 views
0

我正在使用此函数进行zlib压缩,并想知道outbuffer变量是否应设置为特定大小?它是否将字符数组限制在这里?我可以放在这里的长度是否有限制?将它转换为std :: string是否有意义,因为Im在C++中编译?zlib C++压缩缓冲区的字符大小

/** Compress a STL string using zlib with given compression level and return 
    * the binary data. */ 
    std::string compress_string(const std::string& str, int compressionlevel = 9) 
    { 
     z_stream zs;      // z_stream is zlib's control structure 
     memset(&zs, 0, sizeof(zs)); 

     if (deflateInit(&zs, compressionlevel) != Z_OK) 
      throw(std::runtime_error("deflateInit failed while compressing.")); 

     // For the compress 
     deflateInit2(&zs, compressionlevel, Z_DEFLATED,MOD_GZIP_ZLIB_WINDOWSIZE + 16,MOD_GZIP_ZLIB_CFACTOR,Z_DEFAULT_STRATEGY) != Z_OK; 

     zs.next_in = (Bytef*)str.data(); 
     zs.avail_in = str.size();   // set the z_stream's input 

     int ret; 
     char outbuffer[3222768]; 
     std::string outstring; 

     // retrieve the compressed bytes blockwise 
     do { 
      zs.next_out = reinterpret_cast<Bytef*>(outbuffer); 
      zs.avail_out = sizeof(outbuffer); 

      ret = deflate(&zs, Z_FINISH); 

      if (outstring.size() < zs.total_out) { 
       // append the block to the output string 
       outstring.append(outbuffer,zs.total_out - outstring.size()); 
      } 
     } 
     while (ret == Z_OK); 

     deflateEnd(&zs); 

     if (ret != Z_STREAM_END) {   // an error occurred that was not EOF 
      std::ostringstream oss; 
      oss << "Exception during zlib compression: (" << ret << ") " << zs.msg; 
      throw(std::runtime_error(oss.str())); 
     } 

     return outstring; 
    } 
+1

Take aook [at this SO post](http://stackoverflow.com/questions/8902924/zlib-deflate-how-much-memory-to-allocate) – LPs

+0

如果你看看[zlib示例](http ://www.zlib.net/zlib_how.html)你会看到它使用的缓冲区大小只有16k。 –

回答

0

这就是deflateBound()的用途。你的deflateInit2()后,你可以调用它的输入大小,它会给你一个可能的扩展当压缩不可压缩的数据的约束。

顺便说一句,在相同的结构上调用deflateInit/deflateInit2两次会导致大的内存泄漏。请给他们打一次电话。您应该完整阅读zlib documentation

+0

嗨,只是想知道你的意思是我应该从我的代码中删除deflateInit if语句? –

+0

您需要删除'deflateInit()'或'deflateInit2()'。第二个永远泄漏第一个分配的内存。顺便说一下,第二个末尾的'!= Z_OK'是令人困惑的,因为它什么也不做。 –