boost::iostreams 解压缩返回一个空流

boost::iostreams decompression returns an empty stream

本文关键字:一个 iostreams 解压缩 返回 boost      更新时间:2023-10-16

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

我一直只是尝试使用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 <<filteredStream.rdbuf(); 而不是 boost::iostreams::copy

  • 使用filtering_istreambuf filtering_istream的本质(有什么区别?我应该什么时候使用每一个?

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

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

我觉得我缺少一个基本概念,谁能帮我弄清楚吗?

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

对于 bzip2 压缩,在这两种情况下都会引发异常。这可能与解压缩器缓冲区大小有关吗? 在这个阶段,我变得非常绝望。

提前谢谢大家!

你用了两次str。第一次使用它后,它处于流的末尾,因此第二次不会读取任何内容。

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

住在科里鲁

#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