protobuf(quickStart)
1.简介
Protocol Buffers是Google开发的一种数据描述语言,能够将数据进行序列化,可用于数据存储、通信协议等方面。
可以理解成更快、更简单、更小的JSON或者XML,区别在于Protocol Buffers是二进制格式,而JSON和XML是文本格式。
相对于XML,Protocol Buffers有如下几个优点:
1.简洁。
2.体积小,消息大小只有XML的1/10到1/3。
3.速度快,解析速度比XML快20~100倍。
4.使用Protocol Buffers的编译器,可以生成更容易在编程中使用的数据访问代码。
5.更好的兼容性,Protocol Buffers设计的一个原则就是要能够很好的支持向下或向上兼容。
使用不同的数据描述语言序列化后的字节个数比对:
使用不同的数据描述语言进行序列化以及反序列化的响应时间比对:
*数据在网络进行传输时要经历三个阶段: 发送方对数据进行序列化、网络中传输、接收方反序列化。
将对象序列化成protobuf、xml、json结构时,protobuf所占的字节数量最少、有效数据的比重最大、总数据最少,因此决定了数据在网络进行传输时所耗费的时间最少。
将对象序列化成protobuf、xml、json结构以及反序列化成对象时,protobuf所耗费的时间最少。
结论:数据使用protobuf序列化格式能够大大提高生产效率(服务的响应时间)。
2.proto文件的语法规则
字段类型
*目前有v2、v3版本,不同版本的语法稍微有些不同,会额外进行说明,以下是v2版本的语法规则。
2.1 消息
1.使用message关键字定义消息,并指定消息的名称(取一个有意义的名字)
2.指定字段的类型和名称
3.添加字段的约束
4.定义字段的编号(从1开始,其中19000~19999被Protocol Buffers作为保留字段)
最基本的message
message User{
required int32 id = 1;
required string username = 2;
required string password = 3;
optional string email = 4;
}
字段约束
required指定该字段必须赋值。
optional表示该字段允许为空,可以使用[default]指定默认值,如果没有指定默认值则会使用字段类型的默认值。
- 对于strings ,默认是一个空string。
- 对于bytes ,默认是一个空的bytes。
- 对于bools ,默认是false。
- 对于数值类型 ,默认是0。
- 对于枚举,默认是第一个定义的枚举值,必须为0。
repeated指定字段为集合。
oneof指定一组字段中必须有一个字段要赋值。
*在一个proto文件中可以同时定义多个message类型,生成代码时根据生成代码的目标语言不同,处理的方式不太一样( 对于Java, 每个proto文件都生成一个类,即一个.java文件,每个message、enum类型都是该类的静态内部类 )
message User{
required int32 id = 1;
//username或email之间必须有一个字段要赋值
oneof login{
string username = 3;
string email = 4;
}
required string password = 2;
} message Admin{
required int32 id = 1;
required string username = 2;
required string password = 3;
}
*可以指定字段的类型为其他的message类型。
message Course{
required User user = 1;
required string cour_name = 2;
} message User{
required int32 id = 1;
required string username = 2;
required string password = 3;
optional string email = 4;
}
*在proto文件中支持类型的嵌套,即定义的message类型仅作为包含其message类型的字段类型( 此时Course静态内部类中包含User静态内部类 )
message Course{
message User{
required int32 id = 1;
required string username = 2;
required string password = 3;
optional string email = 4;
}
required User user = 1;
required string cour_name = 2;
}
*使用extensions关键字预留消息类型的字段编号,通过extend关键字继续定义。
message User{
//30~100编号为User类型私有.
extensions 30 to 100
} extend User{
required int32 id = 1;
required string username = 2;
required string password = 3;
optional string email = 4;
}
2.2 枚举
1.使用enum关键字定义枚举,并指定枚举的名称(取一个有意义的名字)
2.设置枚举可能包含的值并定义编号(从1开始,其中19000~19999被Protocol Buffers作为保留字段)
最基本的枚举:
enum Course{
Chinese = ;
Mathematics = ;
English = ;
}
*可以使用import关键字导入其他proto文件。
*可以使用option java_package设置生成java类的包名。
*可以使用option java_outer_classname设置生成java类的类名。
import "other.proto"
option java_package = "com.zht.protobuf";
option java_outer_classname = "UserModel";
message User{
required int32 id = 1;
required string username = 2;
required string password = 3;
optional string email = 4;
}
3.proto2与proto3的不同
1.proto文件的第一行必须使用syntax属性指定使用的protobuf版本:proto2、proto3。
2.移除了 “required” 字段约束。
3.“optional”字段约束改名为 “singular”。
4.在 proto2 中, "optional" 约束可以使用 default 指定字段的默认值(不指定也不赋值则跟随系统), 在 proto3 中, 字段的默认值只能根据字段类型由系统决定。
*当字段被设置为默认值时, 该字段不会被序列化, 提高效率。
5.枚举类型的第一个字段的编号必须为 0 。
4.protobuf的使用
1.环境的准备
在github下载对应操作环境的protobuf工具包: https://github.com/google/protobuf/releases
windows用户选择: protoc-3.5.1-win32.zip
解压后配置环境变量PATH,使其在上下文能直接搜索 protoc.exe。
2.编写.proto文件
E:\proto\user.proto
内容如下:
#v3版本需要在proto文件的第一行使用syntax属性指定proto文件使用的语法的版本
syntax = "proto2";
option java_package = "com.zht.protobuf";
option java_outer_classname = "UserModel";
message User{
required int32 id = 1;
required string username = 2;
required string password = 3;
optional string email = 4;
}
3.使用protoc.exe命令生成实体
protoc.exe -I [proto文件所在目录] --java_out [JAVA类存放目录] [proto文件绝对路径]
4.将实体放入工程进行实体的构造和赋值
将实体放入工程:
构造并且赋值:
public class Main { public static void main(String[] args) throws InvalidProtocolBufferException {
//获取构造器并进行赋值
UserModel.User.Builder builder = UserModel.User.newBuilder();
builder.setId(1);
builder.setUsername("zhuanght");
builder.setPassword("123456");
builder.setEmail("aiuzht119@163.com"); //获取实体
UserModel.User user = builder.build(); System.out.println("源数据:\r"+ user.toString());
System.out.println("序列化后:"+Arrays.toString(user.toByteArray())); //模拟接收Byte[],反序列化成User实体
byte[] data =user.toByteArray();
User u = User.parseFrom(data);
System.out.println("\r解析:\r" +u.toString());
} }
打印结果 :
源数据:
id: 1
username: "zhuanght"
password: "123456"
email: "aiuzht119@163.com" 序列化后:[8, 1, 18, 8, 122, 104, 117, 97, 110, 103, 104, 116, 26, 6, 49, 50, 51, 52, 53, 54, 34, 17, 97, 105, 117, 122, 104, 116, 49, 49, 57, 64, 49, 54, 51, 46, 99, 111, 109] 解析:
id: 1
username: "zhuanght"
password: "123456"
email: "aiuzht119@163.com"
5.获取序列化后的字节数组在网络中进行传输
5.protobuf实例与json进行转换
导入相关依赖
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.4</version>
</dependency>
protobuf实例序列化为json格式
//user为上面例子的UserModel.User消息实例
String json = JsonFormat.printToString(user)
json序列化为protobuf实例
//builder为上面例子的UserModel.User.Builder构造器实例
JsonFormat.merge(json ,builder);
//此时再使用构建器创建的实例就包含转换后的数据
builder.build();
protobuf(quickStart)的更多相关文章
- SuperSocket与Netty之实现protobuf协议,包括服务端和客户端
今天准备给大家介绍一个c#服务器框架(SuperSocket)和一个c#客户端框架(SuperSocket.ClientEngine).这两个框架的作者是园区里面的江大渔. 首先感谢他的无私开源贡献. ...
- grpc python quickstart
参考:grpc python quickstart 准备 1.升级pip $ python -m pip install --upgrade pip 2.安装grpc $ python -m pip ...
- python通过protobuf实现rpc
由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...
- Protobuf使用规范分享
一.Protobuf 的优点 Protobuf 有如 XML,不过它更小.更快.也更简单.它以高效的二进制方式存储,比 XML 小 3 到 10 倍,快 20 到 100 倍.你可以定义自己的数据结构 ...
- java netty socket库和自定义C#socket库利用protobuf进行通信完整实例
之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...
- 在Wcf中应用ProtoBuf替代默认的序列化器
Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...
- protobuf的编译安装
github地址:https://github.com/google/protobuf支持多种语言,有多个语言的版本,本文采用的是在centos7下编译源码进行安装. github上有详细的安装说明: ...
- 编译protobuf的jar文件
1.准备工作 需要到github上下载相应的文件,地址https://github.com/google/protobuf/releases protobuf有很多不同语言的版本,因为我们需要的是ja ...
- protobuf学习(2)-相关学习资料
protobuf官方git地址 protobuf官方英文文档 (你懂的需要FQ) protobuf中文翻译文档 protobuf概述 (官方翻译 推荐阅读) protobuf入门 ...
随机推荐
- 转:客户端session与服务端session
会话(Session)跟踪是Web程序中常用的技术,用来 跟踪用户的整个会话 .常用的会话跟踪技术是Cookie与Session. Cookie通过在客户端记录信息确定用户身份 , Session通过 ...
- 利用 DirectShow 开发自己的 Filter
学习directshow已经有几天了,下面将自己的学习心得写下来,希望对其他的人有帮助. Filter实质是个COM组件,所以学习开发Filter之前你应该对com的知识有点了解.Com组件的实质是一 ...
- RFM模型+SOM聚类︱离群值筛选问题
笔者寄语:一般情况下离群值不应该直接删除,应该进行筛选,然后进行专门的离群值分析.笔者在这进行一下思考,在聚类基础之上的一种离群点检验. 基于聚类的离群点检测的步骤如下:数据标准化--聚类-- ...
- 【linux】 LINUX FTP搭建
1.安装ftp服务 yum install vsftpd 2.编辑配置文件 vsftpd的配置文件有三个,分别是:/etc/vsftpd/vsftpd.conf/etc/vsftpd/ftpusers ...
- ROM型启动方式概述
ROM 型启动方式概述 所有的VxWorks 内核映像类型中,只有VxWorks 类型使用的bootrom 引导程序进行启动,此时VxWorks 内核映像放置在主机端,由目标板bootrom 完成Vx ...
- XP硬盘读写速度很慢的解决方法
05购入的电脑,今日仍在发挥余热,但系统速度慢得出奇.今日检测了硬盘读写速度还不到2m/s,实在令人难以接受.一查之下,硬盘被置为PIO模式了,难怪. 用以下方法得以解决: 1.对桌面"我的 ...
- R语言自动化报告格式——knitr
R语言自动化报告格式--knitr 相关文献: R语言自动化报告格式--knitr 资讯 | R Notebooks 即将发布 ------------------------------------ ...
- directX播放程序
enum PLAYSTATE {Stopped, Paused, Running, Init};PLAYSTATE g_Current=Init;HWND ghApp;HINSTANCE g ...
- Java中的List转换成JSON报错(一)
1.错误描述 Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang/ ...
- C# 中?和??的用法
最近在看官方的源码时,经常看到有 Int? sum; 和 FileProvider = FileProvider ??builder.GetFileProvider(); 一个问号: 很多数据类型时不 ...