flatbuffers/protobuf+java

前言:

公司业务需求是相机端与java服务端通过nanomsg进行交互,而传输消息就用到了 flatbuffers/protobuf进行对消息的序列化和反序列化。

1、flatbuffers/protobuf

有人会问这两个东西到底是干什么的,你可以把json当成他两个的兄弟来理解,毕竟json还是比较大众化的。想要再网络上进行数据传输时,就需要进行序列化,即将传输对象进行流化,之后便可对对象进行读写。
序列化就是: 对象—>buffer
反序列化是: buffer—>对象
实际开发应用就是:我们相机端使用c写的,云端是java写的,双方如何相互之间发送并接收消息。这时候flatbuffers和protobuf就出来了:他们会先给双方定义一份协议,双方拿着这份协议去对应不同的语言生成不同的代码。c通过协议发送序列化后的消息给java,java拿到消息后,再根据协议进行反序列化,ok,消息就收到了,结束。

2、java+flatbuffers

1、下载flatbuffers源码

地址:源码
然后将java下的目录文件copy到项目:eg
在这里插入图片描述

2、下载编译器

下载地址
俺没用过苹果,只知道windows
解压后,会有 flact.exe应用程序
在这里插入图片描述

3、编辑schema 文件,生成java

在编译器同级目录下建一个文本文档,将下面内容写上去

namespace com.xtuer.bean;

table Cml {
    name:string;
    age:int;
}

root_type Cml;

记住,要将后文件后缀改为fbs
然后cmd 到这个目录下 执行:flatc --java Cml.fbs
这时候你会发现目录下生成了一个com.flat.bean.Cml.java
copy进项目
整体结构:
在这里插入图片描述

4、运行demo

package com.flat.bean;

import com.google.flatbuffers.FlatBufferBuilder;

import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * @author mlcheng
 * @date 2022/10/21 14:53
 */
public class FlatBuffersDemo {
    private static final String FILE_NAME = "E:\\谷歌下载\\test.txt";

    public static void main(String[] args) throws Exception {
        fasong();
        jieshou();
    }

    public static void fasong(){
        // 创建 CMl对象
        FlatBufferBuilder builder = new FlatBufferBuilder();
        int root = Cml.createCml(builder, builder.createString("cml"), 18);
        builder.finish(root);
        //  序列化 对象为字节码
        byte[] buffer = builder.sizedByteArray();
        System.out.println(buffer);
        System.out.println(Arrays.toString(buffer));
    }


    public static void jieshou() throws Exception {
        byte[] buf = {12, 0, 0, 0, 8, 0, 12, 0, 4, 0, 8, 0, 8, 0, 0, 0, 8, 0, 0, 0, 18, 0, 0, 0, 3, 0, 0, 0, 99, 109, 108, 0};
        ByteBuffer buffer = ByteBuffer.wrap(buf);
        Cml cml = Cml.getRootAsCml(buffer);
        System.out.println("Name: " + cml.name() + ", Age: " + cml.age());
    }
}

运行发送方法:
在这里插入图片描述
运行接收的方法:
在这里插入图片描述
接收的buf就是复制发送过来的字节,结束,打通。

3、java+protobuf

1、下载idea插件

File->settings->Plugins->GenProtobuf
在这里插入图片描述

2、pom.xml中引入依赖

<dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.grpc/grpc-all -->
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
            <version>1.11.0</version>
        </dependency>

<build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.5.0.Final</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.5.0</version>
                <configuration>
                    <protocArtifact>
                        com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}
                    </protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>
                        io.grpc:protoc-gen-grpc-java:1.11.0:exe:${os.detected.classifier}
                    </pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
  </build>

3、编写.proto文件,生成java类

新建一个proto文件夹,编写一个.proto文件
在这里插入图片描述

syntax = "proto3";
//生成文件所在包名
option java_package = "com.xinhuan.llpr.cloud.proto";
//生成的java文件名
option java_outer_classname = "CloudProto";

message Cloud {
    string name = 1;
    int32 age = 2;
}

然后右边maven打开 点击protobuf:compile
在这里插入图片描述
这是你就会发现生成了一个.java
在这里插入图片描述
把这个.java复制到项目中,但是最好不要动他的路径,我之所以在.proto命名为这个路径,是因为我项目的结构就是这样的,需要根据自己的项目来定义
复制成功后:
在这里插入图片描述
这就是为什么不要随便移动,包的路径最好相同,因为人家自动给我们生成的东西,最好不要改了。

4、demo

package com.xinhuan.llpr.cloud.proto;

import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;

import java.util.Arrays;

/**
 * @author mlcheng
 * @date 2022/10/21 15:53
 */
public class ProtobufDemo {
    public static void main(String[] args) throws InvalidProtocolBufferException {
        CloudProto.Cloud.Builder cloudBUilder = CloudProto.Cloud.newBuilder();
        cloudBUilder.setAge(18);
        cloudBUilder.setName("cml");
        CloudProto.Cloud cloud = cloudBUilder.build();

        System.out.println("对象:\n"+cloud);

        byte[] cloudBytes = cloud.toByteArray();
        System.out.println("长度:"+cloudBytes.length);

        System.out.println("序列化后:"+cloudBytes+"-------"+ Arrays.toString(cloudBytes));

        CloudProto.Cloud cloud1 = CloudProto.Cloud.parseFrom(cloudBytes);
        System.out.println("反序列化后:\n"+cloud1);

        System.out.println( "序列化后转成json形式:"+ JsonFormat.printer().print(cloud1));
    }
}

运行结果:
在这里插入图片描述

总结:

其实这两个demo 我们就能看出flatbuffers和protobuf的区别:
同样的name和age,可以明显看出protobuf的byte长度小,flatbuffers的长度长
即:flat的序列化后的数据比proto大,运行时的内存是proto的两倍左右,但就是因为他的内存大,所以他的反序列化速度嘎嘎快。有利有弊,我们最后用的是protobuf。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值