選單

protobuf 資料型別

protobuf 資料型別

protobuf 資料型別

protobuf作為支援多種程式語言的序列化庫,有豐富的資料型別。同時資料型別,既能獨立於各種程式語言內嵌的資料型別,又能與它們,對應和轉換。message複合型別是交換資料的單元。在message中,定義資料型別欄位,裝載資料。

標量資料型別

protobuf定義的標量資料型別,其對應於C++中的資料型別,名稱上基本相同。 int32->int32_t , int64->int64_t , string->string等。

protobuf 資料型別

protobuf的資料型別與C++,Java,Python和Go語言中的資料型別都有一一對應的關係。

protobuf 資料型別

protobuf 資料型別

複合型別

oneof型別

類似C語言的union。

message SampleMessage { oneof test_oneof { string name = 4; SubMessage sub_message = 9; }}

Map型別

類似STL的map。map型別不能巢狀定義。

map map_field = N;

不用map時,用下面的等價形式。

message MapFieldEntry { optional key_type key = 1; optional value_type value = 2;}repeated MapFieldEntry map_field = N;

RPC服務介面型別

。proto檔案中定義rpc service介面。

service SearchService { //rpc介面函式是Search //引數是SearchRequest,返回SearchResponse Search (SearchRequest) returns (SearchResponse);}

實現上述介面的client和server端舉例。

RPC client

using google::protobuf;protobuf::RpcChannel* channel;protobuf::RpcController* controller;SearchService* service;SearchRequest request;SearchResponse response;void DoSearch() { // You provide classes MyRpcChannel and MyRpcController, which implement // the abstract interfaces protobuf::RpcChannel and protobuf::RpcController。 channel = new MyRpcChannel(“somehost。example。com:1234”); controller = new MyRpcController; // The protocol compiler generates the SearchService class based on the // definition given above。 service = new SearchService::Stub(channel); // Set up the request。 request。set_query(“protocol buffers”); // Execute the RPC。 service->Search(controller, request, response, protobuf::NewCallback(&Done));}void Done() { delete service; delete channel; delete controller;}

RPC Server。

using google::protobuf;class ExampleSearchService : public SearchService { public: void Search(protobuf::RpcController* controller, const SearchRequest* request, SearchResponse* response, protobuf::Closure* done) { if (request->query() == “google”) { response->add_result()->set_url(“http://www。google。com”); } else if (request->query() == “protocol buffers”) { response->add_result()->set_url(“http://protobuf。googlecode。com”); } done->Run(); }};int main() { // You provide class MyRpcServer。 It does not have to implement any // particular interface; this is just an example。 MyRpcServer server; protobuf::Service* service = new ExampleSearchService; server。ExportOnPort(1234, service); server。Run(); delete service; return 0;}

proto3新增的資料型別

標量資料型別支援更多的語言,增加支援Ruby,C#,PHP和Dart。

protobuf 資料型別

protobuf 資料型別

protobuf <-> JSON 定義 type-by-type對應關係。這是proto3最實用的特性了。

如果JSON編碼資料中缺少某個值,或者其值為null,則在解析為protobuf時,它將被解釋為相應的預設值。

如果欄位在protobuf中具有預設值,則預設情況下將在JSON編碼的資料中省略該欄位以節省空間。

protobuf 資料型別

Any資料型別(開發中的功能)

類似C++中的泛型。

import “google/protobuf/any。proto”;message ErrorStatus { string message = 1; repeated google。protobuf。Any details = 2;}

proto3新增的特性

欄位定義無需再加required 和 optional。

message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3;}

enum型別必須定義0值

“every enum definition must contain a constant that maps to zero as its first element。”

雜項

訊息巢狀定義和巢狀使用

類似C語言結構體巢狀。

訊息擴充套件

欄位佔位符,給未來使用。實際是沒有定義這些欄位。

message Foo { extensions 100 to 199;}

在欄位序號126上定義一個欄位。

extend Foo { optional int32 bar = 126;}

使用擴充套件欄位。

Foo foo;foo。SetExtension(bar, 15);

package

定義名稱空間。

package foo。bar;message Open { 。。。 }

引用定義過的包。

message Foo { 。。。 foo。bar。Open open = 1; 。。。}

C++產生的名稱空間:

foo::bar

引用其它.proto檔案

在。proto的開頭使用import。

import “myproject/other_protos。proto”;

生成程式碼

protoc ——proto_path=IMPORT_PATH ——cpp_out=DST_DIR ——java_out=DST_DIR ——python_out=DST_DIR path/to/file。proto

多條訊息的流式化

protobuf的二進位制格式不能自我界定。protobuf不能確定訊息的二進位制邊界。同時輸出多個訊息時,要自己定義訊息的邊界。一種方法,將訊息的位元組大小先寫出,然後再寫出訊息本身。

不支援大資料集

但是用protobuf作為大資料集中的部分。

訊息不能自描述

原始的訊息,如果沒有proto檔案,是無法解析的。

protobuf 資料型別