1. 程式人生 > >輕量級序列化庫boost serialization

輕量級序列化庫boost serialization

物件序列化是專案中最經常看到的場景,因此實現該功能的庫也有很多,如: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?
  1. #include <fstream>
  2. // 文字方式存檔
  3. #include <boost/archive/text_oarchive.hpp>
  4. #include <boost/archive/text_iarchive.hpp>
  5. /////////////////////////////////////////////////////////////
  6. // gps coordinate
  7. //
  8. // illustrates serialization for a simple type
  9. //
  10. class gps_position  
  11. {  
  12. private:  
  13. friendclass boost::serialization::access;//置入式
  14. template<class Archive>  
  15. void serialize(Archive & ar, const unsigned int version)  
  16.     {  
  17.         ar & degrees;//序列化或反序列化&操作符比>>和<<更為方便
  18.         ar & minutes;  
  19.         ar & seconds;  
  20.     }  
  21. int degrees;  
  22. int minutes;  
  23. float seconds;  
  24. public:  
  25.     gps_position(){};  
  26.     gps_position(int d, int m, float s) :  
  27.         degrees(d), minutes(m), seconds(s)  
  28.     {}  
  29. };  
  30. int main() {  
  31.     std::fstream ofs("filename");  
  32. // create class instance
  33. const gps_position g(35, 59, 24.567f);  
  34. // save data to archive
  35.     {  
  36.         boost::archive::text_oarchive oa(ofs);  
  37.         oa << g;  
  38.     }  
  39. // ... some time later restore the class instance to its orginal state
  40.     gps_position newg;  
  41.     {  
  42.         std::fstream ifs("filename");  
  43.         boost::archive::text_iarchive ia(ifs);  
  44.         ia >> newg;  
  45.     }  
  46. return 0;  
  47. }  
2.非置入實現 [cpp] view plaincopyprint?
  1. #include <boost/archive/text_oarchive.hpp>
  2. #include <boost/archive/text_iarchive.hpp>
  3. class gps_position  
  4. {  
  5. public:  
  6. int degrees;  
  7. int minutes;  
  8. float seconds;  
  9.     gps_position(){};  
  10.     gps_position(int d, int m, float s) :  
  11.         degrees(d), minutes(m), seconds(s)  
  12.     {}  
  13. };  
  14. namespace boost {  
  15. namespace serialization {  
  16. template<class Archive>  
  17. void serialize(Archive & ar, gps_position & g, const unsigned int version)//必須包含在boost::serialization名字空間下
  18. {  
  19.     ar & g.degrees;  
  20.     ar & g.minutes;  
  21.     ar & g.seconds;  
  22. }  
  23. // namespace serialization
  24. // namespace boost

3.可以序列化類物件,但被序列化的類必須實現序列化函式

[cpp] view plaincopyprint?
  1. class bus_stop  
  2. {  
  3. friendclass boost::serialization::access;  
  4. template<class Archive>  
  5. void serialize(Archive & ar, const unsigned int version)  
  6.     {  
  7.         ar & latitude;  
  8.         ar & longitude;  
  9.     }  
  10.     gps_position latitude;  
  11.     gps_position longitude;  
  12. protected:  
  13.     bus_stop(const gps_position & lat_, const gps_position & long_) :  
  14.     latitude(lat_), longitude(long_)  
  15.     {}  
  16. public:  
  17.     bus_stop(){}  
  18. // See item # 14 in Effective C++ by Scott Meyers.
  19. // re non-virtual destructors in base classes.
  20. virtual ~bus_stop(){}  
  21. };  

4.繼承關係的序列化

[cpp] view plaincopyprint?
  1. #include <boost/serialization/base_object.hpp>//必須包含這個標頭檔案
  2. class bus_stop_corner : public bus_stop  
  3. {  
  4. friendclass boost::serialization::access;  
  5. template<class Archive>  
  6. void serialize(Archive & ar, const unsigned int version)  
  7.     {  
  8. // serialize base class information
  9.         ar & boost::serialization::base_object<bus_stop>(*this);//序列化基類
  10.         ar & street1;  
  11.         ar & street2;  
  12.     }  
  13.     std::string street1;  
  14.     std::string street2;  
  15. virtual std::string description() const
  16.     {  
  17. return street1 + " and " + street2;  
  18.     }  
  19. public:  
  20.     bus_stop_corner(){}  
  21.     bus_stop_corner(const gps_position & lat_, const gps_position & long_,  
  22. const std::string & s1_, const std::string & s2_  
  23.     ) :  
  24.         bus_stop(lat_, long_), street1(s1_), street2(s2_)  
  25.     {}  
  26. };  

5.序列化陣列

[cpp] view plaincopyprint?
  1. class bus_route  
  2. {  
  3. friendclass boost::serialization::access;  
  4.     bus_stop stops[10];  
  5. template<class Archive>  
  6. void serialize(Archive & ar, const unsigned int version)  
  7.     {  
  8.         ar & stops;//會自動在前面加上陣列的長度
  9.     }  
  10. public:  
  11.     bus_route(){}  
  12. };  

6.序列化stl容器

[cpp] view plaincopyprint?
  1. #include <boost/serialization/list.hpp>
  2. class bus_route  
  3. {  
  4. friendclass boost::serialization::access;  
  5.     std::list<bus_stop> stops;  
  6. template<class Archive>  
  7. void serialize(Archive & ar, const unsigned int version)  
  8.     {  
  9.         ar & stops;//會自動加上容器的長度
  10.     }  
  11. public:  
  12.     bus_route(){}  
  13. };  

7.可根據版本號序列化

[cpp] view plaincopyprint?
  1. #include <boost/serialization/list.hpp>
  2. #include <boost/serialization/string.hpp>
  3. #include <boost/serialization/version.hpp> //必須包含這個標頭檔案
  4. class bus_route  
  5. {  
  6. friendclass boost::serialization::access;  
  7.     std::list<bus_stop> stops;  
  8.     std::string driver_name;  
  9. template<class Archive>  
  10. void serialize(Archive & ar, const unsigned int version)  
  11.     {  
  12. // only save/load driver_name for newer archives
  13. if(version > 0)//根據版本號序列化
  14.             ar & driver_name;  
  15.         ar & stops;  
  16.     }  
  17. public:  
  18.     bus_route(){}  
  19. };  
  20. BOOST_CLASS_VERSION(bus_route, 1) //定義version=1

8.讀寫分離

一直以來都是serialize這個函式做序列化很反序列化,但有時候序列化和反序列化的方法不一致,serialize函式就難以支援了,因此要用save/load函式,save做序列化操作,而load做反序列化操作。

[cpp] view plaincopyprint?
  1. #include <boost/serialization/list.hpp>
  2. #include <boost/serialization/string.hpp>
  3. #include <boost/serialization/version.hpp>
  4. #include <boost/serialization/split_member.hpp>
  5. class bus_route  
  6. {  
  7. friendclass boost::serialization::access;  
  8.     std::list<bus_stop> stops;  
  9.     std::string driver_name;  
  10. template<class Archive>  
  11. void save(Archive & ar, const unsigned int version) const
  12.     {  
  13. // note, version is always the latest when saving
  14.         ar  & driver_name;  
  15.         ar  & stops;  
  16.     }  
  17. template<class Archive>  
  18. void load(Archive & ar, const unsigned int version)  
  19.     {  
  20. if(version > 0)  
  21.             ar & driver_name;  
  22.         ar  & stops;  
  23.     }  
  24.     BOOST_SERIALIZATION_SPLIT_MEMBER() //這個巨集定義必須要在類中加上
  25. public:  
  26.     bus_route(){}  
  27. };  
  28. BOOST_CLASS_VERSION(bus_route, 1)