1. 什么是序列化?
程序猿在編寫應用程序的時候往往須要將程序的某些數據存儲在內存中,然后將其寫入某個文件或是將它傳輸到網絡中的還有一台計算機上以實現通訊。這個將程序數據轉化成能被存儲並傳輸的格式的過程被稱為“序列化”(Serialization),而它的逆過程則可被稱為“反序列化”(Deserialization)。
簡單來說,序列化就是將對象實例的狀態轉換為可保持或傳輸的格式的過程。與序列化相對的是反序列化,它依據流重構對象。這兩個過程結合起來,能夠輕松地存儲和數據傳輸。比如,能夠序列化一個對象,然后使用 HTTP 通過 Internet 在client和server之間傳輸該對象。
總結
序列化:將對象變成字節流的形式傳出去。
反序列化:從字節流恢復成原來的對象。
2. 為什么要序列化?優點在哪里?
簡單來說,對象序列化通經常使用於兩個目的:
(1) 將對象存儲於硬盤上 ,便於以后反序列化使用
(2)在網絡上傳送對象的字節序列
對象序列化的優點在哪里?網絡傳輸方面的便捷性、靈活性就不說了,這里舉個我們常常可能發生的需求:你有一個數據結構,里面存儲的數據是經過非常多其他數據通過非常復雜的算法生成的,因為數據量非常大,算法又復雜,因此生成該數據結構所用數據的時間可能要非常久(或許幾個小時,甚至幾天),生成該數據結構后又要用作其他的計算,那么你在調試階段,每次執行個程序,就光生成數據結構就要花上這么長的時間,無疑代價是非常大的。假設你確定生成數據結構的算法不會變或不常變,那么就能夠通過序列化技術生成數據結構數據存儲到磁盤上,下次又一次執行程序時僅僅須要從磁盤上讀取該對象數據就可以,所花費時間也就讀一個文件的時間,可想而知是多么的快,節省了我們的開發時間。
3. C++對象序列化的四種方法
將C++對象進行序列化的方法一般有四種,以下分別介紹:
3.1 Google Protocol Buffers(protobuf)
Google Protocol Buffers (GPB)是Google內部使用的數據編碼方式,旨在用來取代XML進行數據交換。可用於數據序列化與反序列化。主要特性有:
- 高效
- 語言中立(Cpp, Java, Python)
- 可擴展
3.2 Boost.Serialization
Boost.Serialization能夠創建或重建程序中的等效結構,並保存為二進制數據、文本數據、XML或者實用戶自己定義的其它文件。該庫具有下面吸引人的特性:
- 代碼可移植(實現僅依賴於ANSI C++)。
- 深度指針保存與恢復。
- 能夠序列化STL容器和其它經常使用模版庫。
- 數據可移植。
- 非入侵性。
3.3 MFC Serialization
Windows平台下可使用MFC中的序列化方法。MFC 對 CObject 類中的序列化提供內置支持。因此,全部從 CObject 派生的類都可利用 CObject 的序列化協議。
3.4 .Net Framework
.NET的執行時環境用來支持用戶定義類型的流化的機制。它在此過程中,先將對象的公共字段和私有字段以及類的名稱(包含類所在的程序集)轉換為字節流,然后再把字節流寫入數據流。在隨后對對象進行反序列化時,將創建出與原對象全然同樣的副本。
3.5 簡單總結
這幾種序列化方案各有優缺點,各有自己的適用場景。當中MFC和.Net框架的方法適用范圍非常窄,僅僅適用於Windows下,且.Net框架方法還須要.Net的執行環境。參考文獻1從序列化時間、反序列化時間和產生數據文件大小這幾個方面比較了前三種序列化方案,得出結論例如以下(僅供參考):
- Google Protocol Buffers效率較高,可是數據對象必須預先定義,並使用protoc編譯,適合要求效率,同意自己定義類型的內部場合使用。
- Boost.Serialization 使用靈活簡單,並且支持標准C++容器。
- 相比而言,MFC的效率較低,可是結合MSVS平台使用最為方便。
為了考慮平台的移植性、適用性和高效性,推薦大家使用Google的protobuf和Boost的序列化方案,以下介紹我使用這兩種方案的心得及注意事項。