一、前言
1、在程式設計中有時會有這樣的需求:
- 儲存記憶體中的對象到磁盤上,下次運作時直接讀取該對象,不用再重新指派,對于那些對象特别大,指派時間長的對象來說能大大提高速度。比如我現在有一個存儲着100萬條資料的Map對象,如果把Map中的每條資料存入磁盤,然後再進行讀取重新insert的話,這樣耗時肯定很久;如果把Map對象直接儲存到磁盤中,然後讀取檔案,讀取出來不用重新insert,直接用,這樣将會更友善
- 通過網絡傳輸對象
2、序列化
能實作上面操作的方法叫做序列化:
序列化在計算機科學中通常有以下定義:
對同步控制而言,表示強制在同一時間内進行單一存取。
在資料儲存與傳送的部分是指将一個對象存儲至一個儲存媒介,例如檔案或是記億體緩沖等,或者透過網絡傳送資料時進行編碼的過程,可以是位元組或是XML等格式。而位元組的或XML編碼格式可以還原完全相等的對象。這程式被應用在不同應用程式之間傳送對象,以及伺服器将對象儲存到檔案或資料庫。相反的過程又稱為反序列化。
3、Boost Serialization
Boost 提供的序列化操作起來非常簡單,先看一個非常簡單的例子:
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
struct employee
{
int id;
int age;
employee()
:id(),age() {}
employee(int id_,int age_) :id(id_),age(age_) {}
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & id;
ar & age;
}
};
void save(const employee& es)
{
std::ofstream ofs("data");
boost::archive::text_oarchive oa(ofs);
oa << es;
}
void load(employee& es)
{
std::ifstream ifs("data");
boost::archive::text_iarchive ia(ifs);
ia >> es;
}
int main()
{
employee e1(,);
save(e1);
employee e2;
load(e2);
return ;
}
這樣e2就和e1相同了。
需要注意的是,自定義的結構或類中必須實作serialize方法,然後把需要儲存的成員寫在函數裡。
除了可以儲存自定義類型外,還可以儲存STL中的各類容器,但是需要注意一點,因為需要實作serialize方法,是以引入的頭檔案不是STL的頭檔案,而是Booat實作的頭檔案。例如想儲存vector對象,那麼需要引入
#include < boost/serialization/vector.hpp >,其他類型同理。
其他
1、如果不想改變類中的函數,新增serialize函數,還可以采用這種
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar, employee& g, const unsigned int version)
{
ar & g.id;
ar & g.age;
}
} // namespace serialization
}
2、如果自定義類型中含有位域的會,直接采用以上方法會出錯,正确的方法如下
struct Test
{
char bits1 : ;
char bits2 : ;
char bits3 : ;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
char tmp1 = bits1;
char tmp2 = bits2;
char tmp3 = bits3;
ar & BOOST_SERIALIZATION_NVP(tmp1);
ar & BOOST_SERIALIZATION_NVP(tmp2);
ar & BOOST_SERIALIZATION_NVP(tmp3);
bits1 = tmp1;
bits2 = tmp2;
bits3 = tmp3;
}
}