Protobuf入门
简介
Protobuf全称是Google Protocol Buffer,是一种高效轻便的结构化数据存储方式,可用于(数据)通信协议、数据存储等。
也可以理解为结构化数据的序列化方法,可简单类比为XML(这里主要是指在数据通信和数据存储这些应用场景中序列化方面的类比,但个人认为XML作为一种扩展标记语言和Protobuf还是有着本质区别的),其具有以下特点:
-
语言无关,平台无关
Protobuf 支持Java, C++, Python 等多种语言,支持多个平台。
-
高效
比XML更小(3~10倍),更快(20 ~ 100倍),更为简单。
-
扩展性,兼容性好
可以更新数据结构,而不影响和破坏原有的旧程序。
序列化和反序列化
将结构数据或对象转换成能够被存储和传输(例如网络传输)的格式,同时应当要保证这个序列化结果在之后(可能在另一个计算环境中)能够被重建回原来的结构数据或对象。
XML、JSON和ProtoBuf
- XML、JSON、ProtoBuf 都具有数据结构化和数据序列化的能力
- XML、JSON 更注重数据结构化,关注人类可读性和语义表达能力。ProtoBuf 更注重数据序列化,关注效率、空间、速度,人类可读性差,语义表达能力不足(为保证极致的效率,会舍弃一部分元信息)
- ProtoBuf 的应用场景更为明确,XML、JSON 的应用场景更为丰富。
ProtoBuf API
protoc为message的每个required
字段和optional
字段都定义了以下几个函数(不限于这几个):
1 TypeName xxx() const; //获取字段的值
2 bool has_xxx(); //判断是否设值
3 void set_xxx(const TypeName&); //设值
4 void clear_xxx(); //使其变为默认值
为每个repeated
字段定义了以下几个:
1 TypeName* add_xxx(); //增加结点
2 TypeName xxx(int) const; //获取指定序号的结点,类似于C++的"[]"运算符
3 TypeName* mutable_xxx(int); //类似于上一个,但是获取的是指针
4 int xxx_size(); //获取结点的数量
下面几个是常用的序列化函数:
1 bool SerializeToOstream(std::ostream * output) const; //输出到输出流中
2 bool SerializeToString(string * output) const; //输出到string
3 bool SerializeToArray(void * data, int size) const; //输出到字节流
与之对应的反序列化函数:
1 bool ParseFromIstream(std::istream * input); //从输入流解析
2 bool ParseFromString(const string & data); //从string解析
3 bool ParseFromArray(const void * data, int size); //从字节流解析