gpt4 book ai didi

c++ - 如何连接 Boost 序列化和 iostream 以将对象序列化和 gzip 到字符串?

转载 作者:IT老高 更新时间:2023-10-28 12:58:06 33 4
gpt4 key购买 nike

我一直在使用 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;
}

问题是,我刚刚发现也需要压缩我的序列化数据,所以我正在考虑使用 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;
}

但无法弄清楚如何正确保存到压缩字符串。问题是我没有刷新过滤器链,但我尝试了弹出和同步,但似乎没有任何效果。这是我损坏的代码:

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();
}

因此,一些数据卡在某处的流缓冲区中,当我知道它应该是 43K 左右的(有效)输出时,我总是得到一些完整的压缩数据 block (16K 或 32K)我使用我的 saveGZFile 方法。显然连接 ofstream 关​​闭并正确刷新,但连接 ostringstream 没有。

有什么帮助吗? (这是我的第一个 stackoverflow 问题——帮帮我,伙计们,你们是我唯一的希望!)

最佳答案

回到这个问题,我意识到我必须在去年的某个时候修复它(因为我现在正在使用 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();
}

只要让整个链条超出范围,它就可以工作!整洁的!为了完整起见,这是我的加载器:

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;
}

关于c++ - 如何连接 Boost 序列化和 iostream 以将对象序列化和 gzip 到字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1753469/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com