Boost序列化:如何预测序列化结果的大小
Boost Serialization : How To Predict The Size Of The Serialized Result?
我是这样使用boost序列化的:
Header H(__Magic, SSP_T_REQUEST, 98, 72, 42, Date(), SSP_C_NONE);
Header Z;
std::cout << H << std::endl;
std::cout << std::endl;
char serial_str[4096];
std::memset(serial_str, 0, 4096);
boost::iostreams::basic_array_sink<char> inserter(serial_str, 4096);
boost::iostreams::stream<boost::iostreams::basic_array_sink<char> > s(inserter);
boost::archive::binary_oarchive oa(s);
oa & H;
s.flush();
std::cout << serial_str << std::endl;
boost::iostreams::basic_array_source<char> device(serial_str, 4096);
boost::iostreams::stream<boost::iostreams::basic_array_source<char> > s2(device);
boost::archive::binary_iarchive ia(s2);
ia >> Z;
std::cout << Z << std::endl;
它工作得很好。
然而,我需要在套接字上发送这些数据包。我的问题是,我怎么知道在另一边我需要读取多少字节?序列化结果的大小不是常量,而且比struct的sizeof要大。
我如何确保另一边的数据是完整的?我使用循环缓冲区,但序列化怎么办?
谢谢所有的
一般来说,这是无法预测的。这(很大程度上)取决于存档格式。但是使用对象跟踪可以省略完整的子图,而使用动态类型信息可以添加大量数据。
如果你可以为序列化的数据提供临时缓冲区,你可以先序列化到一个缓冲区,然后在发送有效负载之前发送大小(现在你知道了)。
将会有
的开销- 对象跟踪(通过指针/引用序列化)
- 动态多态性(通过(智能)指针到基序列化)
- 版本控制(除非您为涉及的类型禁用它)
- 存档头文件(除非已禁用)
- 代码转换(除非禁用)
这里有一些答案,可以为您提供有关这些调整点的更多信息:
- Boost c++序列化开销
- Boost序列化二进制存档给出不正确的输出
- 矢量
Boost序列化 - 调整事物(boost::archive::no_codecvt, boost::archive::no_header,禁用跟踪等)
如果您的所有数据都是POD,则很容易预测大小。
开箱即用
如果您在同一台机器上共享IPC,并且您已经在使用循环缓冲区,请考虑将循环缓冲区放入共享内存。
我有很多答案(搜索managed_shared_memory
或managed_mapped_file
)的例子。
即使你选择/需要流消息(例如通过网络),你仍然可以使用例如Managed External Buffers。因此,即使不要求所有数据都是POD,也可以避免进行任何序列化。(诀窍是在内部使用offset_ptr<>
代替原始指针,使所有引用都是相对的)。
创建自己的流媒体类并覆盖xsputn
方法。
class counter_streambuf : public std::streambuf {
public:
using std::streambuf::streambuf;
size_t size() const { return m_size; }
protected:
std::streamsize xsputn(const char_type* __s, std::streamsize __n) override
{ this->m_size += __n; return __n; }
private:
size_t m_size = 0;
};
用法:
Header H(__Magic, SSP_T_REQUEST, 98, 72, 42, Date(), SSP_C_NONE);
counter_streambuf csb;
boost::archive::binary_oarchive oa(csb, boost::archive::no_header);
oa & H;
cout<<"Size: "<<csb.size();
相关文章:
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 在不同平台上序列化和应对UINT64_T-不同的结果
- 在执行二进制序列化时,删除字符串流结果的const-ness是否安全?
- Boost序列化:如何预测序列化结果的大小