04 序列化与反序列化

序列化与反序列化

1. quick start

protobuf

syntax = "proto3";

enum Color
{
Red = 0;
Green = 5;
Yellow = 6;
Blue = 9;
}

message Person
{
int32 id = 1;
repeated bytes name = 2;
bytes sex = 3;
int32 age = 4;
Color color = 5;
}

C++

#include "Person.pb.h"

void test()
{
// 序列化
Person p;
p.set_id(10);
p.set_age(32);
p.set_sex("man");

p.add_name();
p.set_name(0,"路飞");
p.add_name("艾斯");
p.add_name("萨博");
p.mutable_addr()->set_addr("北京市长安区天安门");
p.mutable_addr()->set_num(1001);
p.set_color(::Color::Blue);

// 序列化对象 p, 最终得到一个字符串
std::string output;
p.SerializeToString(&output);

// 反序列化数据
Person pp;
pp.ParseFromString(output);
std::cout << pp.id() << ", " << pp.sex() << ", " << pp.age() << std::endl;
int size = pp.name_size();
for(int i=0; i<size; ++i)
{
std::cout << pp.name(i) << std::endl;
}
std::cout << pp.color() << std::endl;
}

2. 序列化

序列化是指将数据结构或对象转换为可以在储存或传输中使用的二进制格式的过程。在计算机科学中,序列化通常用于将内存中的对象持久化存储到磁盘上,或者在分布式系统中进行数据传输和通信。

头文件目录: google\protobuf\message_lite.h

Protobuf 中为我们提供了相关的用于数据序列化的 API,如下所示:

  • 序列化到内存中

  • 序列化到文件磁盘中

// --- 将序列化的数据 数据保存到内存中
// 将类对象中的数据序列化为字符串, c++ 风格的字符串, 参数是一个传出参数
bool SerializeToString(std::string* output) const;
// 将类对象中的数据序列化为字符串, c 风格的字符串, 参数 data 是一个传出参数
bool SerializeToArray(void* data, int size) const;

// 将数据序列化写入到磁盘文件中, c++ 风格
// ostream 子类 ofstream -> 写文件
bool SerializeToOstream(std::ostream* output) const;
// 将数据序列化写入到磁盘文件中, c 风格, linux特有文件描述符
bool SerializeToFileDescriptor(int file_descriptor) const;

3. 反序列化

反序列化是指将序列化后的二进制数据重新转换为原始的数据结构或对象的过程。通过反序列化,我们可以将之前序列化的数据重新还原为其原始的形式,以便进行数据的读取、操作和处理。

头文件目录: google\protobuf\message_lite.h

Protobuf 中为我们提供了相关的用于数据序列化的 API,如下所示:

  • 从内存中反序列化

  • 从磁盘文件中反序列化

// 从字符串中读出
bool ParseFromString(const std::string& data) ;
bool ParseFromArray(const void* data, int size);

// 从文件或流中读出
bool ParseFromIstream(std::istream* input);
bool ParseFromFileDescriptor(int file_descriptor);