我有一个看似基本的问题,我在过去几天一直在处理,似乎无法找到答案。我已经阅读了类似问题的多个答案,但似乎没有一个对我有用。
我一直在尝试使用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压缩,两种情况都会抛出异常。它可能与解压缩缓冲区大小有关吗? 在这个阶段我变得无望......
提前谢谢大家!
答案 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