boost :: iostreams decompression返回一个空流

时间:2017-03-29 12:08:36

标签: c++ boost compression gzip iostream

我有一个看似基本的问题,我在过去几天一直在处理,似乎无法找到答案。我已经阅读了类似问题的多个答案,但似乎没有一个对我有用。

我一直在尝试使用boost的压缩/解压缩功能,但我认为我必须使用它不正确。我的目标很简单 - 创建一个字符串,压缩它并写入文件,读取压缩文件,解压缩并打印到std :: cout(或任何其他流)。 我使用了以下代码:

// write files
std::stringstream str;
str << "SampleString";

std::ofstream outFile_raw("rawFile");
std::ofstream outFile_comp("compressedFile);

boost::iostreams::filtering_istream filteredString;
filteredString.push(boost::iostreams::zlib_compressor());
filteredString.push(str);

boost::iostreams::copy(str, outFile_raw);
boost::iostreams::copy(filteredString, outFile_comp);

\\read files
std::ifstream inFile_raw("rawFile");
std::ifstream inFile_comp("compressedFile);

boost::iostreams::filtering_istream filteredInput;
filteredInput.push(boost::iostreams::zlib_decompressor());
filteredInput.push(inFile_comp);

boost::iostreams::copy(inFile_raw, std::cout);
boost::iostreams::copy(filteredInput, std::cout);

写入阶段应该正常工作 - 创建两个文件,一个具有预期大小(stringLength字节)和一个较小的文件。 在阅读时,由于某种原因,只有原始文件被成功读取,而压缩文件只能打印出来。

为了调试这个问题,我尝试了几种方法:

  • 使用seekg和tellg获取流长度,以验证流确实是空的

  • 使用stream&lt;&lt; filteredStream.rdbuf();而不是boost :: iostreams :: copy

  • 使用filtering_istreambuf过滤了一个filter_istream(有什么区别?我什么时候应该使用每个?)

  • 使用其他压缩算法,例如gzip和bzip2。

  • 添加inFile_comp.close();在将其推送到过滤流之前和之后(一种方法没有帮助,另一种方法产生一个iostream流错误异常。

我觉得我缺少一个基本概念,有人可以帮我解决一下吗?

编辑:在进一步调查问题后,我遇到了一个有趣的情况 - 在zlib和gzip压缩期间,整个过程成功完成一个小文件(~5KB,压缩到~200字节),但是对于更大的文件(~55MB,压缩到~320KB),会抛出“iostream stream error”异常。

对于bzip2压缩,两种情况都会抛出异常。它可能与解压缩缓冲区大小有关吗? 在这个阶段我变得无望......

提前谢谢大家!

1 个答案:

答案 0 :(得分:0)

您使用str两次。在第一次使用它之后它在流末端,所以第二次不会读取任何内容。

除此之外,要么显式刷新流和缓冲区,要么限制对象的范围以便它自动发生:

<强> Live On Coliru

#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/copy.hpp>
#include <fstream>
#include <iostream>
#include <sstream>

int main() {
    // write files
    {
        std::stringstream str("SampleString");
        std::ofstream outFile_raw("rawFile");
        boost::iostreams::copy(str, outFile_raw);
    }
    {
        std::stringstream str("SampleString");
        std::ofstream outFile_comp("compressedFile");

        boost::iostreams::filtering_istream filteredString;
        filteredString.push(boost::iostreams::zlib_compressor());
        filteredString.push(str);

        boost::iostreams::copy(filteredString, outFile_comp);

        outFile_comp.flush();
        outFile_comp.close();
    }

    //read files
    {
        std::ifstream inFile_raw("rawFile");
        boost::iostreams::copy(inFile_raw, std::cout << "\n inFile_raw: ");
    }
    {
        std::ifstream inFile_comp("compressedFile");

        boost::iostreams::filtering_istream filteredInput;
        filteredInput.push(boost::iostreams::zlib_decompressor());
        filteredInput.push(inFile_comp);

        boost::iostreams::copy(filteredInput, std::cout << "\n filteredInput: ");
    }
}

打印:

 inFile_raw: SampleString
 filteredInput: SampleString
相关问题