一、proto文件

PB的定义是通过proto文件进行定义的,一个标准的类型如下:

message SearchRequest {
required string query = 1;
optional int32 page_number = 2 [default = 10];
optional int32 result_per_page = 3;
}

其中message定义了类型名字,其中每一个字段有三个选项:

  • required:字段必填。
  • optional: 字段选填,不填就会使用默认值,默认数值类型的默认值为0,string类型为空字符串,枚举类型为第一个枚举值。
  • repeated: 数组类型,可以放入多个类型实例。

之后需要跟上数据类型,在类型之后为字段名。最后跟上“=N”这里N是标记位,每个字段都有标记位,各个字段不能重复且必须为正值,其最大值为 2^29 - 1,同时protobuf内部预留了19000到19999不能被用户使用,官方建议将常用的字段放在前面,由于这个字段的大小随着数值大小增加,如1-16只占用一个字节。最后可以跟上自定义的默认值。
在一个proto文件中可以存放多个message,message内部也可以定义message,外部如需调用需要指明对应的层级关系。同时可以使用import引入外部的proto文件:

//引入外部proto文件
import "other.proto";
//引入外部proto文件,并让引入了该文件的proto文件也能访问被引入类型。
import public "other.proto";

还可以在proto文件中各个级别增加部分编译设置,常用包括:

  • java_package:生成的java包名
  • java_outer_classname :生成的java类名
  • optimize_for:设置编译优化级别,SPEED-默认值速度优先,CODE_SIZE-最小代码量,LITE_RUNTIME-最小运行时占用(适用于环境受限的情况)

二、数据类型

基础数据类型

protobuf支持大多数基础数据类型,下表包含常用类型,详细列表见官方文档

.proto java实现 desc
double double  
float float  
int32 int 有符号整形建议使用sint32
uint32 int 无符号整形
sint32 int 有符号整形
int64 long 有符号长整形建议使用sint64
uint64 long 无符号长整形
sint64 long 有符号长整形
bool boolean  
string String  
byte ByteString  

枚举类型

protobuf可以定义枚举类型:

enum EnumType {
TYPEA = 0;
TYPEB = 1;
TYPEC = 2;
}

enum的每行字段都是一个枚举值,等号后面跟的是实际值,默认实际值是不能一样的,但只需要增加一个option配置就可以设置一样的值:

enum EnumType {
option allow_alias = true;
TYPEA = 0;
TYPEB = 0;
TYPEC = 2;
}

自定义数据类型

还有就是自定义的message类型:

message MessageType {
repeated string str = 1;
} message CompositeType {
optional MessageType message = 1;
}

oneof

oneof是一种特殊类型可以绑定一组变量,但是只有最后设置的那个变量才生效,之前的变量都会被清除:

-------proto------
message Foo {
oneof test_oneof {
string name = 1;
int32 id = 2;
}
}
-------java-------
System.out.println(Demo.Foo.newBuilder().setId(1).setName("name").build().toString());
System.out.println(">>>");
System.out.println(Demo.Foo.newBuilder().setName("name").setId(1).build().toString());
-------输出-------
name: "name"
>>>
id: 1

map

map类型可以接受键值对,键可以使用string或数值类型,值可以使用任意类型:

-------proto------
message Foo {
map<string, string> bar = 1;
}
-------java-------
Demo.Foo foo=Demo.Foo.newBuilder().putBar("key1","value1").putBar("key2","value2").build(); FileOutputStream fos=new FileOutputStream("D://person");
foo.writeTo(fos);
fos.close(); FileInputStream fis=new FileInputStream("D://person");
Demo.Foo foo2=Demo.Foo.parseFrom(fis);
System.out.println(foo2.getBarCount());
fis.close();

  

extension

Extension有点类似继承,可以向message对象内增加额外的字段:

message Foo {
// ...
extensions 100 to 199; //首先需要定义100-199为extension字段
} extend Foo {
optional int32 bar = 100; //增加bar字段
}

在使用extension时和普通字段有些不同,Java中如下:

public static void main(String[] args) throws IOException, ClassNotFoundException {
//通过setExtension设置字段值
Demo.Foo foo=Demo.Foo.newBuilder().setExtension(Demo.bar,1).build();
//通过getExtension可以取值
System.out.println(foo.getExtension(Demo.bar)); FileOutputStream fos=new FileOutputStream("D://person");
foo.writeTo(fos);
fos.close(); FileInputStream fis=new FileInputStream("D://person");
//反序列化时需要注册对应的extension字段,不然无法取到extesion的值
ExtensionRegistry registry = ExtensionRegistry.newInstance();
registry.add(Demo.bar);
Demo.Foo foo2=Demo.Foo.parseFrom(fis,registry);
System.out.println(foo2.getExtension(Demo.bar));
fis.close();
}

proto 2 语法的更多相关文章

  1. proto 3 语法

    一.简介 proto3是新版本的protobuf语法.它简化了部分语法,并扩大了支持的语言,Ruby.C#.目前谷歌推荐只在是用新支持的语言或使用新的gRPC框架的时候使用.proto2和proto3 ...

  2. github atom创建自己的语法高亮

    使用atom一段时间了,有些插件还不是很成熟.比如项目中使用protobuf,早就有人写了语法高亮(https://github.com/podgib/atom-protobuf),但是效果不是很好. ...

  3. Protobuf 语法指南

    英文: Proto Buffers Language Guide 本指南描述了怎样使用protocol buffer 语法来构造你的protocol buffer数据,包括.proto文件语法以及怎样 ...

  4. iOS 集成Protobuf,转换proto文件

    原文地址:http://blog.csdn.net/hyq4412/article/details/54891038 附加Homebrew安装地址:https://brew.sh/index_zh-c ...

  5. protobuf 语法 与 protocol-buffers 的使用

    前言 protocol-buffers 是 node.js 平台对支持 protobuf 封装的三方模块,下面的例子都通过 protocol-buffers 的使用来说明. 什么是protobuf G ...

  6. gRPC-Protocol语法指南

    语法指南 (proto3) Defining A Message Type Scalar Value Types Default Values Enumerations Using Other Mes ...

  7. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  8. Protocol buffers 介绍

    Protocol buffers和mxl一样在序列化数据结构时很灵活.高效和智能,但是它的优势在于定义文件更小,读取速度更快,使用更加简单.目前protocol buffers支持C++.java和p ...

  9. Protobuf语言指南(转)

    Protobuf语言指南 l  定义一个消息(message)类型 l  标量值类型 l  Optional 的字段及默认值 l  枚举 l  使用其他消息类型 l  嵌套类型 l  更新一个消息类型 ...

随机推荐

  1. javaEE中config.properties文件乱码解决办法

    http://jingyan.baidu.com/article/ed2a5d1f3381d709f6be17f8.html ————————————————————————————————————— ...

  2. docker 的使用

    docker 学习 1. Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序. 输出Hello world docker run ubuntu:15 ...

  3. MySQL 数据热备份

    mysqlhotcopy使用lock tables.flush tables和cp或scp来快速备份数据库.它是备份数据库或单个表最快的途径,完全属于物理备份,但只能运行在数据库目录所在的机器上. 与 ...

  4. MySQL设置密码复杂度

    MySQL5.6.6版本之后增加了密码强度验证插件validate_password,相关参数设置的较为严格.使用了该插件会检查设置的密码是否符合当前设置的强度规则,若不满足则拒绝设置. 本文采用测试 ...

  5. 我的预约订单页面List

    <%@ page language="java" contentType="text/html;charset=UTF-8"%> <%@ ta ...

  6. Visual Studio 2010 VS IDE 编辑界面出现绿色的点 去掉绿色的空格点

    Visual Studio  2010 VS IDE 编辑界面出现绿色的点 去掉绿色的空格点 Vs乱按一顿忽然出现一堆绿色的点,我去好难看,还不知道什么鬼,查了查其实就是个 每个点表示一个空格 让他显 ...

  7. Abp之工作单元与事务

    环境:Abp1.2 疑问:没有调用工作单元的SaveChanges方法引起的事务提交时机的问题. 例如:有一个应用服务代码如下: public void CreatePhrase(PhraseCrea ...

  8. python set和get实现

    import math class Square: # 正方形 def __init__(self, l): self.length = l # 边长 def __setattr__(self, ke ...

  9. mysql中的事物处理

    首先,事物的概念,保证一组sql语句操作的完整性,在这个过程中要充分考虑到多用户同时访问数据库数据的情况. 关键词有COMMIT,ROLLBACK,,START TRANSACTION

  10. 16-1 ECMA5与ECMA6的函数定义

    ECMA5: function Drag(id){ this.ele = document.getElementById(id); var that = this; this.ele.onmoused ...