这是Protobuf3的系列二: 如何在protobuf中定义更复杂的对象
proto文件
除了定义string, int等基础对象外(protobuf的基础数据结构和Java变量的对应关系见文章末尾),还可以在proto中定义更复杂的对象,详细如下:
定义List列表:值可以是普通变量,也可以复杂对象
message ComplexObject {
repeated string sons = 4;
repeated Result result = 6;
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
定义枚举成员
message ComplexObject {
Gender gender = 5; // Enum值
enum Gender {
MAN = 0;
WOMAN = 1;
定义Any对象:用于定义任意的值
message ComplexObject {
repeated google.protobuf.Any any = 7;
定义Map对象:key,value都可以是复杂对象
message ComplexObject {
map<string, MapVaule> map = 8;
message MapVaule {
string mapValue = 1;
通过 reserved保留 Assigning Tags和filed name用于将来扩展用
message ComplexObject {
reserved 12, 15, 9 to 11;
reserved "foo", "bar";
以上完整proto文件
syntax = "proto3";
import "google/protobuf/any.proto";
option java_package = "com.hry.spring.proto.complex";
option java_outer_classname = "MyComplexObjectEntity";
message ComplexObject {
int32 id = 1;
string name = 2;
string email = 3;
repeated string sons = 4;
Gender gender = 5;
repeated Result result = 6;
repeated google.protobuf.Any any = 7;
map<string, MapVaule> map = 8;
reserved 12, 15, 9 to 11;
reserved "foo", "bar";
enum Gender {
MAN = 0;
WOMAN = 1;
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
message MapVaule {
string mapValue = 1;
生成Java类
生成的方法详细见Protobuf3 的第一个Java demo。生成的MyComplexObjectEntity类见代码
ComplexObject.Builder builder = ComplexObject.newBuilder()
// 对应proto里: int32 id = 1
builder.setId(100)
// 对应proto里:string name = 2
builder.setName("name")
// 对应proto里:string email = 3
builder.setEmail("email")
// 对应proto里:repeated string sons = 4
builder.addSons("Son1")
builder.addSons("Son2")
// 对应proto里:Gender gender = 5
// builder.setGenderValue(Gender.MAN_VALUE)
builder.setGender(Gender.MAN)
// 对应proto里:repeated Result result = 6
Result.Builder r = Result.newBuilder()
r.setTitle("title")
builder.addResult(r.build())
// 对应proto里:repeated google.protobuf.Any any = 7
Any.Builder any = Any.newBuilder()
any.setTypeUrl("typeUrl")
builder.addAny(any.build())
// 对应proto里:map<string, MapVaule> map_field = 8
MapVaule.Builder mapValue = MapVaule.newBuilder()
mapValue.setMapValue("mapValue")
builder.putMap("mapKey", mapValue.build())
// 生成最终的对象
ComplexObject cob = builder.build()
System.out.println("before :"+ cob.toString())
System.out.println("===========ComplexObject Byte==========")
for(byte b : cob.toByteArray()){
System.out.print(b)
System.out.println()
System.out.println(cob.toByteString())
System.out.println("================================")
//模拟接收Byte[],反序列化成Person类
byte[] byteArray =cob.toByteArray()
ComplexObject cob2 = ComplexObject.parseFrom(byteArray)
System.out.println("after :" + cob2.toString())
before :id: 100
name: "name"
email: "email"
sons: "Son1"
sons: "Son2"
result {
title: "title"
any {
type_url: "typeUrl"
map {
key: "mapKey"
value {
mapValue: "mapValue"
===========ComplexObject Byte==========
810018411097109101265101109971051083448311111049344831111105050718511610511610810158910711612111210185114108662010610997112751011211810108109971128697108117101
<ByteString@1b0375b3 size=69>
================================
after :id: 100
name: "name"
email: "email"
sons: "Son1"
sons: "Son2"
result {
title: "title"
any {
type_url: "typeUrl"
map {
key: "mapKey"
value {
mapValue: "mapValue"
protobuf的基础数据结构和Java变量的对应关系
github
定义复杂的对象这是Protobuf3的系列二: 如何在protobuf中定义更复杂的对象proto文件除了定义string, int等基础对象外(protobuf的基础数据结构和Java变量的对应关系见文章末尾),还可以在proto中定义更复杂的对象,详细如下: 定义List列表:值可以是普通变量,也可以复杂对象message ComplexObject { repeated string
上篇文章我们遗留了两个问题
1、protobuf 怎么运用到我们的项目当中?复杂的 List、Map、内嵌对象等等怎么实现?
2、protobuf 怎么和 JSON 互相转换?
别急,我们现在继续深入,学习就是要不断深入了解,只有更深入,你才能体会到学习的快乐和成就感
一、实现 Java 中 复杂的对象嵌套
二、protobuf 和 JSON 互相转换
1. 官方包 :protobuf-2.6.1.tar
2. 可直接引用,支持跨平台: protobuf-2.6.1
3. 编译库的脚本 :build-protobuf-2.6.1.sh
4. 使用脚本编译得到的可执行文件和库 :lib_protobuf-2.6.1
附:Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos/audio/include)
LOCAL_MODULE := MyGame_shared
LOCAL_MODULE_FILENAME := libMyGame
FILE_LIST := hellocpp/main.cpp
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/utils/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/utils/*.c)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/utils/*.cc)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ohters/protobuf-2.6.1/google/protobuf/*.cc)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ohters/protobuf-2.6.1/google/protobuf/io/*.cc)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ohters/protobuf-2.6.1/google/protobuf/stubs/*.cc)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ohters/protobuf-2.6.1/google/protobuf/testing/*.cc)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ohters/libqrencode/*.c)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/ohters/jsoncpp/src/lib_json/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Net/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Net/*.cc)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Net/protoc/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Net/protoc/*.cc)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_WindowUI/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Platform/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Game/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Game/GF_GameData/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/GF_Game/GF_GameHall/*
目录一、Protobuf简介1、第一个.proto文件2、Protobuf使用二、Protobuf数据定义规范1、数据格式2、基本规范3、限定修饰符4、数据类型5、字段默认值
一、Protobuf简介
Protocol Buffer是Google的语言中立的,平台中立的,可扩展机制的,用于序列化结构化数据 - 对比XML,但更小,更快,更简单。您可以定义数据的结构化,然后可以使用特殊生成的源代码轻松地在各种数据流中使用各种语言编写和读取结构化数据。
为什么使用protobuf呢?
protobuf的快速高
这篇指南讲述如何使用Protocol Buffers来结构化你的Protocol Buffer数据,包括.proto文件语法以及如何从.proto文件生成你的访问类型。本文主要涵盖了proto3的语法,proto2的语法参见Proto2 Language Guide。
这是一篇参考教程 -- 本文中诸多功能的分步示例,详见tutorial。
定义消息类型
使用其他消息类型
更新消息类型
Oneof
定义服务
iotex-proto
用于IoTeX区块链交易和gRPC API的Protobuf和实用程序包
\proto包括IoTeX区块链使用的所有核心数据对象和gRPC API的protobuf定义
\golang包含为go语言生成的protobuf文件
安装协议
从安装Google协议缓冲区编译器protoc v3.12.0或更高版本
在版本v1.4.2中安装protoc-gen-go
启用go mod。 安装grpc-gateway 。 基本上,这是您需要的:
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
安装golang模拟
通过Avro将Protobuf转换为Parquet
本示例说明如何使用Parquet的Avro对象模型和Avro对protobuf对象的支持将Protobuf文件转换为Parquet文件。 Parquet具有直接与Protobuf对象一起使用的模块,但是在为其他读取器(如Hive)编写数据时,这并非总是一个好的选择。
原因是Parquet和Protobuf使用相同的架构定义。 两者都支持必需的,可选的和重复的数据字段,并使用重复对数组进行编码。 从Protobuf到Parquet的映射始终为1比1。
其他对象模型(例如Avro)允许数组为null或包含null元素,并具有注释 ,以便使用额外的隐藏层以Parquet的架构格式对这些更复杂的结构进行编码。 与无重复字段相比,使用这种结构的对象模型更多,因此希望在转换时使用它。
使用复杂的LIST结构存储protobuf数据的
文章目录简介使用入门安装准备生成并运行java代码语法变量变量类型变量默认值Tag变量规则废弃变量枚举引用其他的proto文件packagesJSON映射升级proto的原则定义RPC Service命名规范遇到的问题
Protocol buffers 是一种语言无关,平台无关,可扩展的序列化数据的格式,可用于通信协议,数据存储等。Protocol buffers 很适合做数据存储或 R...
可以使用protobuf库中的json_format模块来实现protobuf与json之间的转换。下面是一个使用python代码实现protobuf转换为json的例子:
```python
import json
import protobuf_json
# 定义protobuf消息类型
from my_proto_pb2 import MyMessage
# 创建一个MyMessage对象
my_message = MyMessage()
my_message.id = 1
my_message.name = "test"
my_message.email = "test@example.com"
# 将MyMessage对象转换为json字符串
json_str = protobuf_json.pb2json(my_message)
# 打印json字符串
print(json_str)
其中,my_proto_pb2是一个protobuf消息类型的定义文件,需要根据实际情况进行修改。protobuf_json.pb2json()方法将protobuf消息类型转换为json字符串。