c++ 序列化和反序列化

转载于:

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的序列化方案,以下介绍我使用这两种方案的心得及注意事项。


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的序列化方案,以下介绍我使用这两种方案的心得及注意事项。