Protobuf概述
Protobuf(全称:Protocol Buffers)是由 Google 开发的一种语言中立、平台无关、可扩展的序列化协议。它用于高效地结构化数据的序列化和反序列化。Protobuf 的主要特点是其紧凑、高效和可扩展的编码格式,使其在各种网络通信和数据存储场景中广泛使用。
Protobuf 的基本概念
- .proto 文件:用于定义数据结构的文件,扩展名为 .proto。它描述了消息的结构、字段类型和其他相关信息。
- 消息(Message):在 .proto 文件中定义的数据结构。每个消息包含一个或多个字段,每个字段都有一个唯一的编号。
- 字段(Field):消息中的数据项,每个字段都有一个类型和编号。
- 编译器(protoc):将 .proto 文件编译成目标编程语言的代码生成器工具。
windows安装protobuf
下载protobuf (根据自己选择合适的版本)
下载后解压,配置Path环境变量到bin级目录
验证,打开cmd,输入protoc --version
引入maven依赖
在项目中引入protobuf包,和安装版本尽量保持一致
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.20.3</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.20.3</version>
</dependency>
idea安装 Protobuf 插件
创建proto文件
在对应目录创建ExampleProto.proto文件
syntax = "proto3";
option java_package = "com.lf.java.netty.serialize.protobuf";
option java_outer_classname = "ExampleProto";
//是否需要將生成的类拆分为多个
option java_multiple_files = true;
message ExampleMessage {
int32 id = 1;
string content = 2;
}
- syntax = “proto3” 表示协议版本,
- option java_package = “com.lf.java.netty.serialize.protobuf” 表示生成的类所处的层级(可能需要手动调整文件,不然会报包名错误)
- option java_multiple_files = true 表示需要將生成的类拆分为多个(false 的话就是不需要)
protoc编译文件
在文件位置打开cmd执行如下命令
protoc --java_out=./ ./example.proto
查看生成的文件
测试生成的类
package com.lf.java.netty.serialize.protobuf;
import com.google.protobuf.CodedOutputStream;
import java.nio.ByteBuffer;
public class ExampleMessageMain {
public static void main(String[] args) throws Exception {
// 创建 ExampleMessage 实例
ExampleMessage message = ExampleMessage.newBuilder()
.setId(123)
.setContent("Hello, Protocol Buffers!")
.build();
// 分配一个足够大的 ByteBuffer
ByteBuffer byteBuffer = ByteBuffer.allocate(message.getSerializedSize());
// 创建 CodedOutputStream 并将消息写入 ByteBuffer
CodedOutputStream outputStream = CodedOutputStream.newInstance(byteBuffer);
message.writeTo(outputStream);
// 刷新输出流以确保所有数据已写入
outputStream.flush();
// 准备 ByteBuffer 进行读取
byteBuffer.flip();
// 打印序列化后的字节数组
byte[] byteArray = new byte[byteBuffer.remaining()];
byteBuffer.get(byteArray);
System.out.println("Serialized data: " + java.util.Arrays.toString(byteArray));
// 反序列化 ExampleMessage 实例
ExampleMessage deserializedMessage = ExampleMessage.parseFrom(byteArray);
System.out.println("Deserialized message: " + deserializedMessage);
}
}