1. 用途:编程
把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。网络
2. 优势:数据结构
a.性能好,效率高(时间和空间上比XML好,XML反序列化开销大)socket
b.代码生成机制编程语言
eg:性能
假设订单包括以下属性:ui
--------------------------------spa
时间:time(用整数表示)命令行
客户id:userid(用整数表示)开发
交易金额:price(用浮点数表示)
交易的描述:desc(用字符串表示)
--------------------------------
若是使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto),在该文件中添加一个名为"Order"的message结构,用来描述通信协议中的结构化数据。该文件的内容大体以下:
--------------------------------
message Order
{
required int32 time = 1;
required int32 userid = 2;
required float price = 3;
optional string desc = 4;
}
--------------------------------
而后,使用protobuf内置的编译器编译 该proto。因为本例子的模块是C++,你能够经过protobuf编译器的命令行参数(看“这里 ”),让它生成C++语言的“订单包装类”。(通常来讲,一个message结构会生成一个包装类)
而后你使用相似下面的代码来序列化/解析该订单包装类:
--------------------------------
// 发送方
Order order;
order.set_time(XXXX);
order.set_userid(123);
order.set_price(100.0f);
order.set_desc("a test order");
string sOrder;
order.SerailzeToString(&sOrder);
// 而后调用某种socket的通信库把序列化以后的字符串发送出去
// ......
--------------------------------
// 接收方
string sOrder;
// 先经过网络通信库接收到数据,存放到某字符串sOrder
// ......
Order order;
if(order.ParseFromString(sOrder)) // 解析该字符串
{
cout << "userid:" << order.userid() << endl
<< "desc:" << order.desc() << endl;
}
else
{
cerr << "parse error!" << endl;
}
--------------------------------
有了这种代码生成机制,开发人员就不用再编写协议解析的代码。万一未来需求发生变动,要求给订单再增长一个“状态”的属性,那只须要在Order.proto文件中增长一行代码。对于发送方(模块A),只要增长一行设置状态的代码;对于接收方(模块B)只要增长一行读取状态的代码。
c.支持“向后兼容”和“向前兼容”
“向后兼容”:当模块B升级以后,它可以正确识别模块A发出的老版本的协议。如上例中,因为老版本没有“状态”这个属性,在扩充协议时,能够考虑把“状态”属性设置成为非必填的,或者给“状态”属性设置一个缺省值。
“向前兼容”:当模块A升级之后,模块B可以 正常识别模块A发出的新版本的协议,这时新增长的“状态”属性会被忽略。
d.支持多种编程语言(官方源代码中包含了C++、Java、Python三种语言)
3. 缺点:
a.应用不够广
b.二进制格式致使可读性差
c.缺少自描述