转载自: http://blog.youkuaiyun.com/ajun_studio/article/details/7693056
http://blog.youkuaiyun.com/lujinhong2/article/details/47204095
Protocol buffers是一个用来序列化结构化数据的技术,支持多种语言诸如C++、Java以及Python语言,可以使用该技术来持久化数据或者序列化成网络传输的数据。相比较一些其他的XML技术而言,该技术的一个明显特点就是更加节省空间(以二进制流存储)、速度更快以及更加灵活。目前被大量用于hadoop的RPC通信协议中,所有的RPC函数参数均是使用protobuf定义的。
(1)package用于指明命名空间,以防与其它项目冲突。一般可以不写。
(2)如果指定java_package,则它作为下一步要生成的java类的package,否则package中定义的值将作为java类的package。即java类所在的包为com.zero.proto。
(3)java_outer_classname指定了生成的java类的类名,如果没指定,则使用.proto文件的文件名作为类名。
(4)message表示消息定义,消息之间可以互相嵌套或者调用。
(5)每个字段必须使用以下3个修饰符之一:required, optional, repeated。
将.proto放到解压后的protoc-2.4.1-win32.zip里面的protoc.exe同一级目录,然后cmd cd到该目录再执行:
double double
float float
int32 int 使用可变长编码方式。编码负数时不够高效——如果字段可能含有负数,那么请使用sint32。
int64 long 使用可变长编码方式。编码负数时不够高效——如果字段可能含有负数,那么请使用sint64。
uint32 int[1] Uses variable-length encoding.
uint64 long[1] Uses variable-length encoding.
sint32 int 使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。
sint64 long 使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。
fixed32 int[1] 总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。
fixed64 long[1] 总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。
sfixed32 int 总是4个字节。
sfixed64 long 总是8个字节。
bool boolean
string String 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。
bytes ByteString 可能包含任意顺序的字节数据。
1. 新添加了syntax关键字,以指明proto文件的protobuf协议版本。如:syntax = "proto3";
2. 删除required,只保留repeated。required和optional都不要了,默认就是optional;
3. 支持map,其声明形式如下:map<key_type, value_type> map_field = N;
4. 字段default标记废弃。
简单示例:
http://blog.youkuaiyun.com/lujinhong2/article/details/47204095
Protocol buffers是一个用来序列化结构化数据的技术,支持多种语言诸如C++、Java以及Python语言,可以使用该技术来持久化数据或者序列化成网络传输的数据。相比较一些其他的XML技术而言,该技术的一个明显特点就是更加节省空间(以二进制流存储)、速度更快以及更加灵活。目前被大量用于hadoop的RPC通信协议中,所有的RPC函数参数均是使用protobuf定义的。
1.创建.proto文件
package com.zero.proto;
option java_package = "com.zero.proto";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}
proto文件说明:
(1)package用于指明命名空间,以防与其它项目冲突。一般可以不写。
(2)如果指定java_package,则它作为下一步要生成的java类的package,否则package中定义的值将作为java类的package。即java类所在的包为com.zero.proto。
(3)java_outer_classname指定了生成的java类的类名,如果没指定,则使用.proto文件的文件名作为类名。
(4)message表示消息定义,消息之间可以互相嵌套或者调用。
(5)每个字段必须使用以下3个修饰符之一:required, optional, repeated。
required:一个格式良好的消息一定要含有1个这种字段。表示该值是必须要设置的;
optional:消息格式中该字段可以有0个或1个值(不超过1个)
repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。表示该值可以重复,相当于java中的List。
(6)每个字段都有唯一的一个标识符,可以理解为索引,用于识别各个字段。
2.生成java文件
需要protoc-2.4.1-win32.zip用于生成java文件,protobuf-java-2.4.1.jar,用户客户端调用。https://github.com/google/protobuf/tags中可以找到各个版本的上述文件。将.proto放到解压后的protoc-2.4.1-win32.zip里面的protoc.exe同一级目录,然后cmd cd到该目录再执行:
protoc.exe --java_out=./ msg.proto
此时在这个目录下会生成com\zero\proto\ AddressBookProtos.java。
3.java客户端使用示例
// 序列化:
Person.Persona.Builder b = Person.Persona.newBuilder();
b.setXXX(i);
Person.Persona p = b.build();
byte [] value = p.toByteArray();
// 反序列化:
Person.Persona last = Person.Persona.parseFrom(person);
关于一些方法的使用可参考:
http://www.blogjava.net/DLevin/archive/2015/04/01/424012.aspx
4.proto type --- java type对应关系
proto类型 Java 类型 备注double double
float float
int32 int 使用可变长编码方式。编码负数时不够高效——如果字段可能含有负数,那么请使用sint32。
int64 long 使用可变长编码方式。编码负数时不够高效——如果字段可能含有负数,那么请使用sint64。
uint32 int[1] Uses variable-length encoding.
uint64 long[1] Uses variable-length encoding.
sint32 int 使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。
sint64 long 使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。
fixed32 int[1] 总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。
fixed64 long[1] 总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。
sfixed32 int 总是4个字节。
sfixed64 long 总是8个字节。
bool boolean
string String 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。
bytes ByteString 可能包含任意顺序的字节数据。
5.proto3
Proto3的语法变化1. 新添加了syntax关键字,以指明proto文件的protobuf协议版本。如:syntax = "proto3";
2. 删除required,只保留repeated。required和optional都不要了,默认就是optional;
3. 支持map,其声明形式如下:map<key_type, value_type> map_field = N;
4. 字段default标记废弃。
简单示例:
syntax = "proto3";
package proto3_proto;
message Message
{
enum Humour {
UNKNOWN = 0;
PUNS = 1;
SLAPSTICK = 2;
BILL_BAILEY = 3;
}
string name = 1;
Humour hilarity = 2;
uint32 height_in_cm = 3;
bytes data = 4;
int64 result_count = 7;
bool true_scotsman = 8;
float score = 9;
repeated uint64 key = 5[packed = true];
}
message MessageArray
{
map<string, Message> msg_map = 1;
}