专业的编程技术博客社区

网站首页 > 博客文章 正文

protobuf 数据类型(protobuf bytes类型)

baijin 2024-08-27 11:08:18 博客文章 4 ℃ 0 评论

protobuf 数据类型

protobuf作为支持多种编程语言的序列化库,有丰富的数据类型。同时数据类型,既能独立于各种编程语言内嵌的数据类型,又能与它们,对应和转换。message复合类型是交换数据的单元。在message中,定义数据类型字段,装载数据。

标量数据类型

protobuf定义的标量数据类型,其对应于C++中的数据类型,名称上基本相同。 int32->int32_t , int64->int64_t , string->string等。

protobuf的数据类型与C++,Java,Python和Go语言中的数据类型都有一一对应的关系。

复合类型

oneof类型

类似C语言的union。

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

Map类型

类似STL的map。map类型不能嵌套定义。

map<key_type, value_type> 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 <-> JSON 定义 type-by-type对应关系。这是proto3最实用的特性了。

如果JSON编码数据中缺少某个值,或者其值为null,则在解析为protobuf时,它将被解释为相应的默认值。

如果字段在protobuf中具有默认值,则默认情况下将在JSON编码的数据中省略该字段以节省空间。

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文件,是无法解析的。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表