protobuf使用简介
- 2016-06-06 22:39:00
- admin
- 原创 6684
一、protobuf支持和下载
protobuf 2已经支持Java, Python, and C++,protobuf 3支持更多语言。
最新版本下载地址:protobuf-2.6.1.tar.gz
帮助文档:https://developers.google.com/protocol-buffers/docs/overview
二、编码细节
1、Base 128 Varints对整数进行编码,小整数使用更少字节数。
2、ZigZag编码有符号整数,绝对值小占用更少字节数。
3、[packed=true]对repeated of primitive numeric types能够有效的节约空间(节约key+type)。
proto2默认不pack,proto3默认pack。
4、字符串、对象使用type + len + value编码。
5、Message Structure(key + wire_type + value),key值1到15占用更少空间,更适合repeated元素。
三、编写风格
Message And Field Names:
message SongServerRequest {
required string song_name = 1;
}
Enums:
enum Foo {
FIRST_VALUE = 1;
SECOND_VALUE = 2;
}
Services:
service FooService {
rpc GetSomething(FooRequest) returns (FooResponse);
}
四、安装protobuf和protoc命令
编译protobuf帮助 ./configure -h (--with-pic动态链接库一般需要使用此选项)
./configure && make && make install
protoc命令:
--cpp_out=OUT_DIR C++输出
--java_out=OUT_DIR JAVA输出
--python_out=OUT_DIR python输出
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
五、协议示例
// See README.txt for information and build instructions.
package tutorial;//可以使用点号,表示多个命名空间。
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2; // Unique ID number for this person.
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;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1; //repeated的size可以是0,并且保持顺序
}
六、对象常用方法
bool IsInitialized() const;: checks if all the required fields have been set.
void CopyFrom(const Person& from);: overwrites the message with the given message's values.
void Clear();: clears all the elements back to the empty state.
DebugString、ShortDebugString(不换行)、PrintDebugString调试时使用。
序列化方法:
SerializeToString
ParseFromString
SerializeToOstream
ParseFromIstream//required和optional值后面的会覆盖前面的,repeated会添加到尾部。
MergeFrom//required和optional值后面的会覆盖前面的,repeated会添加到尾部。
以下方法一般情况下不需要调用:
GOOGLE_PROTOBUF_VERIFY_VERSION; //如果版本protobuf版本不对,程序会自动终止
google::protobuf::ShutdownProtobufLibrary();//清除protobuf创建的全局对象
兼容性方法(不能识别的key放到下面的set):
unknown_fields()
unknown_fields().field_count()
七、兼容性
为了向前兼容:(字符串默认值empty string,布尔默认值false,数值默认值0)
1 optional、repeated元素可以被删除。
2 optional、repeated元素可以被添加,但tag不能与以前定义的相同。
八、优化
1 尽量重用对象
2 多线程使用大量小型对象时请使用:Google's tcmalloc
九、java的option
option java_package = "com.example.tutorial"; //该option优先于package指令
option java_outer_classname = "AddressBookProtos"; //该option优先于proto文件名,定义包含所有定义类的类名。
十、java的细节
1 Message是不可以被修改的,Message.Builder是用来创建Message的(设置属性,调用build方法)。
2 序列化方法:
byte[] toByteArray();
void writeTo(OutputStream output);
static Person parseFrom(byte[] data);
static Person parseFrom(InputStream input);
3 maven配置
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.6.1</version>
</dependency>
十一、protobuf和json优劣
protobuf高效
json灵活