0%

C/C++编程—序列化

在程序中往往需要将程序中的某些数据存储在内存中,然后将其写入本地文件或者进行网络传输。将程序数据转化成能被存储和传输的格式的过程称为序列化,它的逆过程称为反序列化。本文主要记录通过Boost.Serialization进行序列化的相关内容。

以下为一个简单的C++序列化程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <string>

struct Student
{
std::string name;
int age;
};

int Serialize(const Student &stu, char out[])
{
int count = 0;
memcpy(out, stu.name.c_str(), stu.name.length());
count += stu.name.length();
memcpy(out + count, &stu.age, sizeof(int));
count += sizeof(int);
return count;
}

int Deserialize(Student &stu, const char* in, int count)
{
int offset = 0;
stu.name.append(in, count - sizeof(int));
offset += stu.name.length();
memcpy(&stu.age, in + offset, sizeof(int));
return 0;
}

int main()
{
char buf[128];
int count = 0;

Student stu1;
stu1.name = "tangming";
stu1.age = 1024;
count = Serialize(stu1, buf);

Student stu2;
Deserialize(stu2, buf, count);
std::cout << "name: " << stu2.name << std::endl;
std::cout << "age: " << stu2.age << std::endl;

system("pause");
return 0;
}

C++中常用的序列化方法主要有protobufBoost.SerializationGoogle Protocol Buffers(protobuf)是Google内部使用的数据编码方式,用来替代XML进行数据交换。protobuf效率较高,但是数据对象必须预先定义,并使用protoc编译,适合要求效率,允许自定义类型的内部场合使用。Boost.Serialization可以创建或重建程序中的等效结构,并保存为二进制数据、文本数据、XML或者有用户自定义的其他文件。Boost.Serialization使用灵活简单,而且支持标准C++容器。

1. Boost.Serialization

Boost.Serialization来自标准Boost安装包,具有轻量、代码可移植、可以序列化STL容器和其他常用模板库的优点。与其他Boost库不同的是,Serialization并不是一个只包含头文件的库,因此需要对其进行编译。
Serialization库把存档和类型的序列化进行了分离,意味着任意的数据类型可以采用任意的格式进行存档。其头文件主要有两个目录:<boost/archive>主要包含存档格式的头文件;<boost/serialization>中的头文件提供了对各种数据类型进行序列化的能力。

1.1 存档

Boost.Serialization 提供了多个归档类,它们可以持久化保存并在某个时刻恢复成C++对象。
|归档类|功能|
|:–:|:–|
|boost::archive::text_oarchive|用来把数据序列化成文本流|
|boost::archive::text_iarchive|用来从文本流恢复数据|
|boost::archive::xml_oarchive|用来把数据序列化成xml|
|boost::archive::xml_iarchive|用来从xml恢复数据|
|boost::archive::binary_oarchive|用来把数据序列化成二进制文件|
|boost::archive::binary_iarchive|用来从二进制文件恢复数据|

只有可序列化的C++类型才能被序列化为字节流,进行存档或恢复。

  • C++的基本类型都可进行序列化,如bool、int、double、enum。
  • 字符串可进行序列化。
  • 可序列化类型的数组也可以序列化。
  • 可序列化类型的指针和引用也可序列化。在序列化指针和引用时,并不会序列化指针中存储的地址,而是对象被自动地序列化。
  • 标准库定义的complexbitsetvalarraypair等可进行序列化,支持标准容器vectordequelistsetmap,不支持stackqueuepriority_queue
  • 可序列化包含序列化函数的自定义数据类型。

1.2 自定义数据类型的序列化

参考文章 & 资源链接