protobuf的使用教程


typora-copy-images-to: assets
typora-root-url: assets

Protocol Buffers

Protocol Buffers介绍

  • Protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化,常用于RPC 系统和持续数据存储系统。
  • 其类似于XML生成和解析,但protobuf的效率高于XML,不过protobuf生成的是字节码,可读性比XML差,类似的还有json、Java的Serializable等。
  • 很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
  • 参考:https://zhuanlan.zhihu.com/p/53339153

Idea 安装protobuf插件

安装插件protobuf Support,之后重启

  • 找到资料包中的protobuf-jetbrains-plugin-0.13.0.zip,在IDEA中安装插件即可

在这里插入图片描述

使用ProtoBuf序列化数据

配置Maven依赖与插件


    <dependencies>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.4.0</version>
        </dependency>
    </dependencies>

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>
        <plugins>
            <!-- Protobuf插件 src/main/java/proto -->
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.0</version>
                <configuration>
                    <protoSourceRoot>${project.basedir}/src/main/java/proto</protoSourceRoot>
                    <protocArtifact>
                        com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}
                    </protocArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

编写 proto 文件

  • protobuf3的语法参考讲义中的「 protobuf3 语法」

  • 在main文件夹下,创建 proto 目录,并编写proto文件

syntax = "proto3";
option java_package = "com.wangjie.protobuf";
option java_outer_classname = "Msg";

message User {
    int32 id = 1;
    string name = 2;
    string sex = 3;
}
message Stats{
    int32 hp =1;
    int32 mp = 2;
    int32 exp =3;
    int32 atk =4;
    int32 def =5;
}

注意:classname不能与message name一样

protobuf与java类型对照表

.proto Type Java Type 备注
double double
float float
int32 int 使用可变长度编码。负数编码效率低下–如果您的字段可能具有负值,请改用sint32。
int64 long 使用可变长度编码。负数编码效率低下–如果您的字段可能具有负值,请改用sint64。
uint32 int 使用可变长度编码。
uint64 long 使用可变长度编码。
sint32 int 使用可变长度编码。有符号的int值。与常规int32相比,它们更有效地编码负数。
sint64 long 使用可变长度编码。有符号的int值。与常规int64相比,它们更有效地编码负数。
fixed32 int 始终为四个字节。如果值通常大于2^28,则比uint32更有效。
fixed64 long 始终为八个字节。如果值通常大于2^56,则比uint64更有效。
sfixed32 int 始终为四个字节。
sfixed64 long 始终为八个字节。
bool boolean
string String 字符串必须始终包含UTF-8编码或7位ASCII文本。
bytes ByteString 可以包含任意字节序列。

执行protobuf:compile编译命令

  • 将 proto 文件编译成java代码

在这里插入图片描述
在这里插入图片描述

编写代码使用ProtoBuf序列化、反序列化

package com.wangjie.protobuf;

import com.google.protobuf.InvalidProtocolBufferException;

public class ProtoBufMsg {
    
    
    public static void main(String[] args) {
    
    
        Msg.User.Builder builder = Msg.User.newBuilder();
        builder.setId(1);
        builder.setName("saber");
        builder.setSex("female");

        byte[] bytes = builder.build().toByteArray();
        System.out.println("--protobuf---");
        for (byte b : bytes) {
    
    
            System.out.print(b);
        }
        System.out.println();
        System.out.println("---");

        try {
    
    
            Msg.User user = Msg.User.parseFrom(bytes);
            System.out.println(user);
        } catch (InvalidProtocolBufferException e) {
    
    
            e.printStackTrace();
        }

        Msg.Stats.Builder statsBuild = Msg.Stats.newBuilder();
        statsBuild.setHp(10);
        statsBuild.setMp(10);
        statsBuild.setExp(10);
        statsBuild.setDef(10);
        statsBuild.setAtk(10);

        byte[] bytes1 = statsBuild.build().toByteArray();
        System.out.println("--protobuf---");
        for (byte b : bytes1) {
    
    
            System.out.print(b);
        }
        System.out.println();
        System.out.println("---");

        Msg.Stats stats = null;
        try {
    
    
            stats = Msg.Stats.parseFrom(bytes1);
        } catch (InvalidProtocolBufferException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(stats);
    }

}

猜你喜欢

转载自blog.csdn.net/qq_36382679/article/details/115000374