輕量級序列化庫boost serialization
阿新 • • 發佈:2019-02-02
物件序列化是專案中最經常看到的場景,因此實現該功能的庫也有很多,如:thrift、protobuf、avro,但我覺得這些庫都太過沉重,因為他們還提供了rpc的功能,如果只是單純做物件序列化,boost serialization是個不錯的選擇,以下boost serialization簡稱BS。
一、程式碼目錄
1.$BOOST_HOME/archive存檔方式類目錄
型別 | 普通位元組 | 寬位元組 |
---|---|---|
二進位制 | binary_iarchive.hpp binary_oarchive.hpp |
binary_wiarchive.hpp binary_woarchive.hpp |
文字 | text_iarchive.hpp text_oarchive.hpp |
text_wiarchive.hpp text_woarchive.hpp |
xml | xml_iarchive.hpp xml_oarchive.hpp |
xml_wiarchive.hpp xml_woarchive.hpp |
2.$BOOST_HOME/serialization 序列化資料型別目錄
目前BS基本上幾乎支援了所有的C++資料型別,還包括指標、陣列等,並且也支援了stl的容器,但要包含相關標頭檔案。
vector.hpp支援vector的序列化
list.hpp支援list的序列化
deque.hpp支援deque的序列化
map.hpp支援map的序列化
hash_map.hpp支援hash_map的序列化
等等...
除了stl的容器,也支援boost的相關容器,如array.hpp
二、序列化類實現
1.置入式實現
[cpp] view plaincopyprint?- #include <fstream>
- // 文字方式存檔
- #include <boost/archive/text_oarchive.hpp>
- #include <boost/archive/text_iarchive.hpp>
- /////////////////////////////////////////////////////////////
- // gps coordinate
- //
- // illustrates serialization for a simple type
- //
- class gps_position
- {
- private:
- friendclass boost::serialization::access;//置入式
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & degrees;//序列化或反序列化&操作符比>>和<<更為方便
- ar & minutes;
- ar & seconds;
- }
- int degrees;
- int minutes;
- float seconds;
- public:
- gps_position(){};
- gps_position(int d, int m, float s) :
- degrees(d), minutes(m), seconds(s)
- {}
- };
- int main() {
- std::fstream ofs("filename");
- // create class instance
- const gps_position g(35, 59, 24.567f);
- // save data to archive
- {
- boost::archive::text_oarchive oa(ofs);
- oa << g;
- }
- // ... some time later restore the class instance to its orginal state
- gps_position newg;
- {
- std::fstream ifs("filename");
- boost::archive::text_iarchive ia(ifs);
- ia >> newg;
- }
- return 0;
- }
- #include <boost/archive/text_oarchive.hpp>
- #include <boost/archive/text_iarchive.hpp>
- class gps_position
- {
- public:
- int degrees;
- int minutes;
- float seconds;
- gps_position(){};
- gps_position(int d, int m, float s) :
- degrees(d), minutes(m), seconds(s)
- {}
- };
- namespace boost {
- namespace serialization {
- template<class Archive>
- void serialize(Archive & ar, gps_position & g, const unsigned int version)//必須包含在boost::serialization名字空間下
- {
- ar & g.degrees;
- ar & g.minutes;
- ar & g.seconds;
- }
- } // namespace serialization
- } // namespace boost
3.可以序列化類物件,但被序列化的類必須實現序列化函式
[cpp] view plaincopyprint?- class bus_stop
- {
- friendclass boost::serialization::access;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & latitude;
- ar & longitude;
- }
- gps_position latitude;
- gps_position longitude;
- protected:
- bus_stop(const gps_position & lat_, const gps_position & long_) :
- latitude(lat_), longitude(long_)
- {}
- public:
- bus_stop(){}
- // See item # 14 in Effective C++ by Scott Meyers.
- // re non-virtual destructors in base classes.
- virtual ~bus_stop(){}
- };
4.繼承關係的序列化
[cpp] view plaincopyprint?- #include <boost/serialization/base_object.hpp>//必須包含這個標頭檔案
- class bus_stop_corner : public bus_stop
- {
- friendclass boost::serialization::access;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- // serialize base class information
- ar & boost::serialization::base_object<bus_stop>(*this);//序列化基類
- ar & street1;
- ar & street2;
- }
- std::string street1;
- std::string street2;
- virtual std::string description() const
- {
- return street1 + " and " + street2;
- }
- public:
- bus_stop_corner(){}
- bus_stop_corner(const gps_position & lat_, const gps_position & long_,
- const std::string & s1_, const std::string & s2_
- ) :
- bus_stop(lat_, long_), street1(s1_), street2(s2_)
- {}
- };
5.序列化陣列
[cpp] view plaincopyprint?- class bus_route
- {
- friendclass boost::serialization::access;
- bus_stop stops[10];
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & stops;//會自動在前面加上陣列的長度
- }
- public:
- bus_route(){}
- };
6.序列化stl容器
[cpp] view plaincopyprint?- #include <boost/serialization/list.hpp>
- class bus_route
- {
- friendclass boost::serialization::access;
- std::list<bus_stop> stops;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- ar & stops;//會自動加上容器的長度
- }
- public:
- bus_route(){}
- };
7.可根據版本號序列化
[cpp] view plaincopyprint?- #include <boost/serialization/list.hpp>
- #include <boost/serialization/string.hpp>
- #include <boost/serialization/version.hpp> //必須包含這個標頭檔案
- class bus_route
- {
- friendclass boost::serialization::access;
- std::list<bus_stop> stops;
- std::string driver_name;
- template<class Archive>
- void serialize(Archive & ar, const unsigned int version)
- {
- // only save/load driver_name for newer archives
- if(version > 0)//根據版本號序列化
- ar & driver_name;
- ar & stops;
- }
- public:
- bus_route(){}
- };
- BOOST_CLASS_VERSION(bus_route, 1) //定義version=1
8.讀寫分離
一直以來都是serialize這個函式做序列化很反序列化,但有時候序列化和反序列化的方法不一致,serialize函式就難以支援了,因此要用save/load函式,save做序列化操作,而load做反序列化操作。
[cpp] view plaincopyprint?- #include <boost/serialization/list.hpp>
- #include <boost/serialization/string.hpp>
- #include <boost/serialization/version.hpp>
- #include <boost/serialization/split_member.hpp>
- class bus_route
- {
- friendclass boost::serialization::access;
- std::list<bus_stop> stops;
- std::string driver_name;
- template<class Archive>
- void save(Archive & ar, const unsigned int version) const
- {
- // note, version is always the latest when saving
- ar & driver_name;
- ar & stops;
- }
- template<class Archive>
- void load(Archive & ar, const unsigned int version)
- {
- if(version > 0)
- ar & driver_name;
- ar & stops;
- }
- BOOST_SERIALIZATION_SPLIT_MEMBER() //這個巨集定義必須要在類中加上
- public:
- bus_route(){}
- };
- BOOST_CLASS_VERSION(bus_route, 1)