10

我实现了文件的 gzip/zlib 解压缩,如 boost 站点上的示例所示。

void CompressionUtils::Inflate(std::ifstream& inputFile,
                               std::ofstream& outputFile)
{
   boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
   in.push(boost::iostreams::gzip_decompressor());
   in.push(inputFile);
   boost::iostreams::copy(in, outputFile);
}

这很好用。我还从一个套接字读取数据,这些数据来自一个基于休息的 JSON 服务,该服务也是压缩的。我想我会写一个基于内存的实现,这有多难。好吧,我发现我不理解流和流缓冲区。我责怪Java的过去几年;)..所以我开始了这条路。

void CompressionUtils::Inflate(char* compressed, 
                               int size,
                               char* decompressed)
{

   boost::iostreams::stream<boost::iostreams::array_source> source(compressed,size);
   //std::stringstream str;

   boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
   in.push(boost::iostreams::gzip_decompressor());
   in.push(source);
   //boost::iostreams::copy(in, str);   
}

但是我不知道我可以使用什么样的流来基本上获得char*解压流的解压表示。这应该很容易,而且可能很容易,但我一直在浪费最后几个小时来提出不成功的尝试。

4

1 回答 1

6

显然,您遇到了过滤流和流缓冲区。您可以反向使用相同的方法将数据放入字符串中。

我手头没有自己的示例,因此请认为这有点伪代码,但这应该是您要查找的内容:

namespace io = boost::iostreams; //<-- good practice
typedef std::vector<char> buffer_t;

void CompressionUtils::Inflate(const buffer_t &compressed,
                               buffer_t &decompressed)
{
    io::filtering_ostream os;

    os.push(io::gzip_decompressor());
    os.push(io::back_inserter(decompressed));

    io::write(os, &compressed[0], compressed.size());
}

所以你可以使用Boost提供的后插入器。

基本上,上面的代码所做的是定义一个可以写入的输出流。它被设置为所有写入它的内容将首先由 解压缩gzip然后附加到back_inserterwhich 将像 back_inserters 那样插入到decompressed缓冲区的后面。

此外,如您所见,缓冲区包含在std::vector. 让我知道这是否适合您。

于 2012-02-19T13:47:52.447 回答