protobuf介绍级使用
介绍
说起 protobuf 首先我第一想到的是 json 和 xml
因为他们都是一种数据传输格式。下面就简单介绍一下protobuf吧
protobuf 是谷歌用于序列化结构化数据(如XML)的语言无关、平台无关、可扩展的机制,他更小、更快和更简单。一旦定义了数据的结构化方式,就可以使用特殊生成的源代码轻松地从各种数据流和使用各种语言编写和读取结构化数据。
下载protobuf
-
下载protocol buffer 的编译器
下载的时候注意一下您要使用的语言版本,目前支持的语言有
c++
c#
java
javascript
object-c
php
python
ruby
dart
-
安装您的编译器(windows)
将下载好的
protoc.exe
编译器放在一个不带中文路径的文件夹内。配置环境变量例如:C:fileprotoc-3.12.3-win64in
-
检查环境变量是否配置成功
打开cmd输入
protoc
看是否有东西输出
格式说明
syntax = "proto3";
option java_package = "com.example.test";//文件选项,生成的java代码所在的目录
option java_outer_classname = "ProBuf";//类名----PersonProBuf.java
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
repeated int32 samples = 4 [packed=true];
reserved 2, 15, 9 to 11;
enum PhoneType {
MOBILE = 0; //枚举类型的第一个默认值为0,必须是0
HOME = 1;
WORK = 2;
}
}
syntax
申明版本,若不申明默认是2.0版本(2.0版本与3.0版本的差异还是蛮大的)required
消息必须传的对象optional
消息可传可不传的对象repeated
相当Listmessage
相当classoption
文件选项可用于操作生成文件后的一系列操作enum
枚举类型reserved
保留字段,在版本改变的时候有用- 使用
//
和/**/
的注释方式
编译protobuf文件为对应的实体类
protoc --proto_path C:UsershysongDesktop --java_out ../src/main/java G:code hriftdemosrcmain
esourceshello.proto
对于各语言生成的对照表
.proto Type | Notes | C++ Type | Java Type | Python Type[2] | Go Type | Ruby Type | C# Type | PHP Type | Dart Type |
---|---|---|---|---|---|---|---|---|---|
double | double | double | float | float64 | Float | double | float | double | |
float | float | float | float | float32 | Float | float | float | double | |
int32 | 使用可变长度编码。编码负数效率低下–如果字段可能有负值,请改用sint32。 | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | int |
int64 | 使用可变长度编码。编码负数效率低下–如果字段可能有负值,请改用sint64。 | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] | Int64 |
uint32 | 使用可变长度编码。 | uint32 | int[1] | int/long[3] | uint32 | Fixnum or Bignum (as required) | uint | integer | int |
uint64 | 使用可变长度编码。 | uint64 | long[1] | int/long[3] | uint64 | Bignum | ulong | integer/string[5] | Int64 |
sint32 | 使用可变长度编码。有符号整型值。这些比普通的int32更有效地编码负数。 | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | int |
sint64 | 使用可变长度编码。有符号整型值。这些比普通的int64更有效地编码负数。 | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] | Int64 |
fixed32 | 总是四个字节。如果值通常大于228,则比uint32更有效。 | uint32 | int[1] | int/long[3] | uint32 | Fixnum or Bignum (as required) | uint | integer | int |
fixed64 | 总是8个字节。如果值通常大于256.uint64,则比uint64更有效 | uint64 | long[1] | int/long[3] | uint64 | Bignum | ulong | integer/string[5] | Int64 |
sfixed32 | 总是四个字节。 | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | int |
sfixed64 | 总是8个字节。 | int64 | long | int/long[3] | int64 | Bignum | long | integer/string[5] | Int64 |
bool | bool | boolean | bool | bool | TrueClass/FalseClass | bool | boolean | bool | |
string | 字符串必须始终包含UTF-8编码或7位ASCII文本,并且长度不能超过232。 | string | String | str/unicode[4] | string | String (UTF-8) | string | string | String |
bytes | 可以包含不超过232的任意字节序列。 | string | ByteString | str | []byte | String (ASCII-8BIT) | ByteString | string | List |
使用方式
JAVA 使用方式
- 项目中导入maven依赖
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.9.0</version>
</dependency>
-
编写protobuf文件并使用命令
protoc --java_out test.proto
生成proto
文件 -
将生成的java文件放入IDE中编写测试代码
public class Test { private static String local = "C:\Users\hysong\Desktop\prototbuf.data"; public static void main(String[] args) throws IOException { // writePB(); PersonPB.Person person = readPB(); System.out.println(person); } private static PersonPB.Person readPB() throws IOException { InputStream inputStream = new FileInputStream(local); PersonPB.Person person = PersonPB.Person.parseFrom(inputStream); return person; } private static void writePB() throws IOException { PersonPB.Person person = PersonPB.Person.newBuilder().setId(1).setName("小红").build(); System.out.printf("person: {%s}", person); @Cleanup FileOutputStream fileOutputStream = new FileOutputStream(local); person.writeTo(fileOutputStream); } }
我们可以打开看下生成的二进制文件
- 这里的protobuf生成的Java对象的toString方法会将属性转换为八进制输出。