boost序列化向前向后兼容

2 篇文章 0 订阅


1.背景描述

在业务中,在读写binary的文件的时候,会统一使用同一binary接口。由于当前的binary接口严格按照顺序进行读写,导致对文件中字段的任何删减,都会造成业务使用新接口对文件的解析失败,程序崩溃。

2.方案描述

2.1 使用的库

使用boost serialization库,本项目中无需导入额外的库,用到的库主要有以下

并且在makefile中添加编译选项-lboost_serialization

2.2 面向场景

  • 新的读写接口读取旧的文件,面向增删改的情况,都可读取成功

  • 旧的读写接口读取新的文件,提示“当前版本过低,应更新接口版本”,程序正常退出

2.3 基本开发方案

  1. 添加类成员函数 serialize(),序列化和反序列化都将调用该接口,将所有的成员变量都添加进来,其中的顺序可以自己定义。所有的STL包括mapvector等都将自动序列化。

    其中,因为成员变量都是private属性,我们添加友元boost::serialization::access

  2. 除此以外,所有的成员变量,如果是内置类型的,都同样需要添加以上的成员函数

  3. 在类的最后,我们为其添加版本控制宏,如不添加,默认的version为0。具体如何使用在后面有说明。
    当一个类被添加了BOOST_CLASS_VERSION后,会在序列化和反序列化的时候将该参数作为void serializa()const unsigned int version传入。

  4. 实际序列化时,以二进制和写文件模式打开文件到ofstream(文件流),以此初始化一个binary_oarchive对象,直接将对象输入到流中,即可完成序列化。

  5. 反序列化时,以二进制和读文件模式打开文件到ifstream(文件流),输出到一个指向对象的指针即可(由于序列化的时候输入的是指向对象的指针,所以反序列化的时候也使用指针)。

2.4 具体实现方案

主要面对以下场景

2.4.1 新接口读旧文件
1)增加了字段

比如新版本添加了m_test字段,在序列化函数中添加对当前版本的判断

由于旧文件没有该属性,因此反序列化出来的对象的m_test是默认值。

2)删除了字段

​ 比如新版本不再需要m_test字段,此时需要注意,为了版本控制,需要在高版本代码中保留该成员变量(不可删除),同时添加版本控制代码如下,在低版本中序列化删除的字段,高版本则跳过

3)修改了字段

​ 道理上跟上一条一样,如将m_test1的类型进行修改,需要保留原来的变量,同时添加版本控制代码。读旧文件时,m_test2为默认值,m_test1有值;读新文件时,m_test2有值,m_test1为默认值。

2.4.2 旧接口读新文件

抛出异常,提示接口版本过旧,需要更新接口(具体处理可再细化)。

实际运行效果,无异常提示,程序正常退出。

3 未来规划

设计具体接口,并和业务下游对接,将接口的改动降低到最小甚至没有。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值