protobuf的序列反序列化
在消息类的父类 MessageLite 中,提供了读写消息实例的方法,包括序列化方法和反序列化方法。
class MessageLite {
public:
//序列化:
bool SerializeToOstream(ostream* output) const; // 将序列
化后数据写入文件流
bool SerializeToArray(void *data, int size) const;
bool SerializeToString(string* output) const;
//反序列化:
bool ParseFromIstream(istream* input); // 从流中读取数
据,再进行反序列化动作
bool ParseFromArray(const void* data, int size);
bool ParseFromString(const string& data);
};
注意:
• 序列化的结果为二进制字节序列,而非文本格式。
• 以上三种序列化的方法没有本质上的区别,只是序列化后输出的格式不同,可以供不同的应用场景使用
• 序列化的 API 函数均为 const 成员函数,因为序列化不会改变类对象的内容, 而是将序列化的结果保存到函数入参指定的地址中
序列化与反序列化的使用
• 创建一个测试文件 info.cc,方法中我们实现:
○ 对一个联系人的信息使用 PB 进行序列化,并将序列化结果打印出来
○ 对序列化后的内容使用 PB 进行反序列,解析出联系人信息并打印出来
#include <iostream>
#include "contacts.pb.h"
int main()
{
contacts::contact conn;
conn.set_sn(10001);
conn.set_name("小明");
conn.set_score(60.5);
//持久化的数据放在str对象里面,这时候可以对str进行持久化传输或者网络传输
std::string str=conn.SerializeAsString();
contacts::contact stu;
bool ret=stu.ParseFromString(str);
if(ret==false)
{
std::cout<<"反序列化失败!\n";
return -1;
}
std::cout<<stu.sn()<<std::endl;
std::cout<<stu.name()<<std::endl;
std::cout<<stu.score()<<std::endl;
return 0;
}
代码书写完成后,编译 info.cc,生成可执行程序
g++ info.cc contacts.pb.cc -o info -std=c++11 -lprotobuf
○ -lprotobuf:链接 protobuf 库文件
○ -std=c++11:支持 C++11
执行可执行程序,可以看见 people 经过序列化和反序列化后的结果
root@VM-4-5-ubuntu:~/demo/protobuf# ./main
10001
小明
60.5
由于 ProtoBuf 是把联系人对象序列化成了二进制序列,这里用 string 来作为接收二进制序列的容器。所以在终端打印的时候会有换行等一些乱码显示。另外相对于 xml 和JSON 来说,因为 PB 被编码成二进制,破解成本增大,ProtoBuf 编码是相对安全的。