protobuf使用简介

2016-06-06 22:39:00
admin
原创 7261
摘要:protobuf使用简介

一、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元素可以被删除。

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灵活

发表评论
评论通过审核之后才会显示。