cce*_*cce 26 c++ boost ostringstream boost-iostreams boost-serialization
我一直在使用Boost序列化库,这实际上非常好,并且让我使用简单的包装器将可序列化对象保存到字符串中,如下所示:
namespace bar = boost::archive;
namespace bio = boost::iostreams;
template <class T> inline std::string saveString(const T & o) {
std::ostringstream oss;
bar::binary_oarchive oa(oss);
oa << o;
return oss.str();
}
template <class T> inline void saveFile(const T & o, const char* fname) {
std::ofstream ofs(fname, std::ios::out|std::ios::binary|std::ios::trunc);
bar::binary_oarchive oa(ofs);
oa << o;
}
template <class T> inline void loadFile(T & o, const char* fname) {
std::ifstream ifs(fname, std::ios::in|std::ios::binary);
assert(ifs.good()); // XXX catch if file not found
bar::binary_iarchive ia(ifs);
ia >> o;
}
Run Code Online (Sandbox Code Playgroud)
问题是,我刚刚发现需要压缩我的序列化数据,所以我正在考虑使用boost :: iostreams中的过滤器.我想出了如何成功地使用文件:
template <class T> inline void saveGZFile(const T & o, const char* fname) {
std::ofstream ofs(fname, std::ios::out|std::ios::binary|std::ios::trunc);
bio::filtering_streambuf<bio::output> out;
out.push(boost::iostreams::gzip_compressor());
out.push(ofs);
bar::binary_oarchive oa(out);
oa << o;
}
template <class T> inline void loadGZFile(T & o, const char* fname) {
std::ifstream ifs(fname, std::ios::in|std::ios::binary);
assert(ifs.good()); // XXX catch if file not found
bio::filtering_streambuf<bio::input> in;
in.push(bio::gzip_decompressor());
in.push(ifs);
bar::binary_iarchive ia(in);
ia >> o;
}
Run Code Online (Sandbox Code Playgroud)
但无法弄清楚如何正确保存到压缩字符串.问题是我没有冲洗过滤器链,但我尝试了弹出和同步,似乎没有任何工作.这是我破碎的代码:
template <class T> inline std::string saveGZString(const T & o) {
std::ostringstream oss;
bio::filtering_streambuf<bio::output> out;
out.push(bio::gzip_compressor());
out.push(oss);
bar::binary_oarchive oa(out);
oa << o;
// XXX out.pop() twice? out.strict_sync()?? oss.flush()??
return oss.str();
}
Run Code Online (Sandbox Code Playgroud)
结果一些数据卡在某个地方的流缓冲区中,当我知道它应该是43K左右时,我总是得到一些完整的块(16K或32K)压缩数据,因为我得到的(有效)输出我的saveGZFile方法.显然连接正确的关闭和冲洗,但钩住ostringstream不会.
有帮助吗?(这是我的第一个stackoverflow问题 - 帮助我,伙计们,你们是我唯一的希望!)
cce*_*cce 20
回到这个问题,我意识到我必须在去年的某个时候修复它(因为我现在正在使用saveGZString).挖掘看我如何修复它,它非常愚蠢/简单:
namespace bar = boost::archive;
namespace bio = boost::iostreams;
template <typename T> inline std::string saveGZString(const T & o) {
std::ostringstream oss;
{
bio::filtering_stream<bio::output> f;
f.push(bio::gzip_compressor());
f.push(oss);
bar::binary_oarchive oa(f);
oa << o;
} // gzip_compressor flushes when f goes out of scope
return oss.str();
}
Run Code Online (Sandbox Code Playgroud)
只是让整个链条超出范围,它的工作原理!整齐!这是我的装载完整性:
template <typename T> inline void loadGZString(T & o, const std::string& s) {
std::istringstream iss(s);
bio::filtering_stream<bio::input> f;
f.push(bio::gzip_decompressor());
f.push(iss);
bar::binary_iarchive ia(f);
ia >> o;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8317 次 |
| 最近记录: |