【JAVA】protobuf的使用

如何在Java中使用protobuf 是一种数据格式,同json,xml,等。但是一种二进制数据格式。 阅读详情

Protobuf的介绍

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

Protobuf和Json的比较

这就是protubuf的一些比较抽象的介绍,不过简单地说,protobuf其实就是一种数据传输的格式,事实上,我们需要知道pb这种格式用来传输数据到底会给我们带来如何的好处.我们可以拿pb格式和json做对比.其实json这种数据传输的格式大家应该非常熟悉.但是json有什么不好的呢,首先json大,json格式是字符串形式,和压缩为二进制的pb格式肯定是要来的大的.此外,json很坑,因为需要对不同的语言编写json解析的程序.......php和python自然可以比较轻松的解析,java就坑了.......而且这些解析器的性能并一致,有好有坏。

.proto文件介绍

message student{
    required int64 sid = 1;//学生id
    required string name = 2;//学生姓名
}

这里面我们发现:

  • message类似于C里面的struct,表示我们定义的是一个消息类型.
  • studeng是具体的类型名称.
  • required是表示这个字段是必须赋值的.
  • int64和string是该字段的类型.
  • =后面的数字表示是该字段在二进制文件中的序号,name为2,表示它一定在sid的后面.

  现在我们如果想要加上一个性别的字段和年龄的字段,性别的字段是enum类型.年龄类型是int32,怎喵加呢?很简单.

enum Sex{
    MALE = 1;
    FEMALE = 2;
}

message Student{
    required int64 sid = 1;//学生id
    required string name = 2;//学生姓名
    optional Sex sex = 3; //学生性别
    optional int32 age = 4;//学生年纪
}

 easy啊.等等,现在我们又有一个消息,比如我们有个班级的消息,希望能够列出里面每个学生的这些基本信息,怎么搞呢?

  首先,我们需要定义一个班级的消息.

message Banji{
     required int64 cid = 1;//班级的id
     required string cname = 2;//班级的编号
     repeated Student students = 3;//学生
}

这里我们要注意几个点:

  • required前缀表示该字段为必要字段,既在序列化和反序列化之前该字段必须已经被赋值。与此同时,在Protocol Buffer中还存在另外两个类似的关键字,optional和repeated,带有这两种限定符的消息字段则没有required字段这样的限制。
  • 标签值为1到15的字段在编码时可以得到优化,既标签值和类型信息仅占有一个byte.标签范围是16到2047的将占有两个bytes,而ProtocolBuffer可以支持的字段数量则为2的29次方减一。有鉴于此,我们在设计消息结构时,可以尽可能考虑让repeated类型的字段标签位于1到15之间,这样便可以有效的节省编码后的字节数量。
  • 在每个消息中必须至少留有一个required类型的字段.
  • 如果打算在原有消息协议中添加新的字段,同时还要保证老版本的程序能够正常读取或写入,那么对于新添加的字段必须是optional或repeated。道理非常简单,老版本程序无法读取或写入新增的required限定符的字段。
  • 在原有的消息中,不能移除已经存在的required字段,optional和repeated类型的字段可以被移除,但是他们之前使用的标签号必须被保留,不能被新的字段重用。
  • int32、uint32、int64、uint64和bool等类型之间是兼容的,sint32和sint64是兼容的,string和bytes是兼容的,fixed32和sfixed32,以及fixed64和sfixed64之间是兼容的,这意味着如果想修改原有字段的类型时,为了保证兼容性,只能将其修改为与其原有类型兼容的类型,否则就将打破新老消息格式的兼容性。

  这里还有一个问题,Banji这个消息要用到Student的定义,我们可以回忆一下java中的处理方式,这种互相定义之间的依赖可以用package和import来解决.这样,我们可以给出完整的.proto的定义方式:

  test.student.proto

package test;
option java_package = "com.songfy.pb";
option java_outer_classname = "StudentProtobuf";
enum Sex{
        MALE = 1;
        FEMALE = 2;
}

message Student{
        required int64 sid = 1;//学生id
        required string name = 2;//学生姓名
        optional Sex sex = 3; //学生性别
        optional int32 age = 4;//学生年纪
}
 test.banji.proto

import "test.student.proto";
package test;
option java_package = "com.songfy.pb";
option java_outer_classname = "BanjiProtobuf";
message Banji{
        required int64 cid = 1;//班级的id
        required string cname = 2;//班级的编号
        repeated Student students = 3;//学生
}

ok,这样我们就把我们的消息类型定义好了....那么如何写代码呢?下面我们细细道来.

编译.proto

protoc --java_out="/usr/home/feng/protos/src" test.banji.proto test.student.proto 
Java代码

package com.songfy.pb;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.songfy.pb.BanjiProtobuf.Banji;
import com.songfy.pb.StudentProtobuf.Sex;
import com.songfy.pb.StudentProtobuf.Student;

public class Main {

    public static void main(String[] args) throws IOException {
        
        //获取student的build sb
        Student.Builder sb = Student.newBuilder();
        //加入两个学生
        sb.setSid(110);
        sb.setName("shuaiguo");
        sb.setSex(Sex.MALE);
        sb.setAge(11);
        
        List<Student> list = new ArrayList<Student>();
        list.add(sb.build());
        
        sb = Student.newBuilder();
        sb.setSid(119);
        sb.setName("lilei");
        sb.setSex(Sex.FEMALE);
        sb.setAge(20);
        
        list.add(sb.build());
        
        //产生一个班级
        Banji.Builder bb = Banji.newBuilder();
        bb.setCid(13);
        bb.setCname("dafengqi");
        bb.addAllStudents(list);
        
        //刷入到文件中
         FileOutputStream fos = new FileOutputStream("C:/Users/songfy/Desktop/test.protoout");
         bb.build().writeTo(fos);
         fos.close();
         
         //从文件读回
         Banji bb1 = Banji.parseFrom(new FileInputStream("C:/Users/songfy/Desktop/test.protoout"));
         System.out.println(bb1.getCid() + "\t" + bb1.getCname());
         for(Student s: bb1.getStudentsList()){
             System.out.println(s.getSid() + "\t" + s.getName() + "\t" + s.getSex() + "\t" + s.getAge());
         }

    }

}

这就是我们代码了,似乎非常easy啊........

这样,我们可以看到输出结果为:

13 dafengqi
110 shuaiguo MALE 11
119 lilei FEMALE 20




节选自:http://www.cnblogs.com/songfy/p/4732560.html




-----------------------------------------------------

请尊重作者劳动成果,

转载请注明出处

关于在Java中如何更简单的使用google protobuf protobuf中的.proto文件能很好的统筹交互双方的协议,但为开发带来了一定阻碍。 在Java里,protobuf使用了immutable(不可变)机制来控制数据的生成源。具体的说,在Java里想要通过protobuf传出一个对象,就要先构造一个该对象的协议文件(.proto文件)的builder对象,通过往这个对象set数据以后,并且调用对象的build方法(由该对象生成一个immutab... 阅读详情

相关推荐

SGLang HiCache实战:手把手教你配置KV Cache Offload,让大模型推理成本直降84%

本文详细介绍了SGLang HiCache在KV Cache Offload配置与调优中的实战应用,通过多级存储架构和智能卸载策略,显著降低大模型推理成本达84%。文章涵盖HiCache架构优势、环境配置、高级调优策略及生产环境最佳实践,帮助开发者优化GPU显存使用,提升并发处理能力。

weixin_29044713的博客 460

Java 中使用 protobuf :入门基础篇,看这篇就够了!

protobuf

m0_37695902的博客 1万+

从CCD数据上报看wxHOOK的封号风险与规避

本文深入分析了微信CCD数据上报机制对wxHOOK的检测逻辑与封号风险,揭示了调试器路径暴露、非白名单DLL加载和内存校验失败等关键风险点。通过实战案例和规避方案,帮助开发者理解如何安全使用wxHOOK技术,避免封号风险,包括内存镜像欺骗、内核级隐蔽和硬件辅助方案等高级技巧。

weixin_27875131的博客 625

java中使用protobuf总结

java中读写protobuf

hsy12342611的专栏 3631

USB通讯速度翻倍秘诀:手把手教你用WinUsb替代HID协议(附Zadig驱动配置图解)

本文详细介绍了如何通过WinUsb技术替代传统HID协议,实现USB通讯速度的显著提升。从技术对比、实现原理到Zadig驱动配置图解,手把手教你完成免驱高速通讯方案,适用于数据采集、固件升级等场景,实测速度可达HID协议的2倍以上。

weixin_29168675的博客 132

Android 12.0 系统systemui状态栏下拉左滑显示通知栏右滑显示控制中心模块的流程分析

在android12.0的系统rom定制化开发中,在系统原生systemui进行自定义下拉状态栏布局的定制的时候,需要在systemui下拉状态栏下滑的时候,根据下滑坐标来 判断当前是滑出通知栏还是滑出控制中心模块,所以就需要根据屏幕宽度,来区分x坐标值为多少是左滑出通知栏或者右滑出控制中心模块,接下来分析下 状态栏下滑坐标等相关功能代码分析

安卓兼职framework和app工程师的博客 2768

java中使用protobuf的详细说明

介绍protobuf在java中的使用

weixin_42684368的博客 2644

深入探讨 SAP ERP 物料主数据中的 Valuation Type

在 SAP ERP 系统中,是用于区分同一种物料在不同条件下的估价方法。物料的估价可以因产地、质量等级、供应商或批次的不同而有所差异。通过为物料设置不同的估价类别,使企业能够对这些差异进行有效管理。为了实现更细致的物料成本核算,SAP 系统通过(分批估价)功能允许为同一物料设置多个估价类型。这种方法特别适合那些在来源、质量、或其他参数上存在显著差异的物料。是 SAP ERP 和 SAP S/4HANA 中物料主数据的核心组成部分,为企业提供了灵活的成本管理工具。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1407

序列化、反序列化原理和Protobuf实现机制

(1)Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程;(2)

长沙老码农 8513

SXU—软件测试方法和技术-朱少民-第四部分 软件测试流程和规范-附考点

软件测试方法和技术-朱少民-第四章 软件测试流程和规范—这本书最后一部分的考点整理,考点分析

weixin_63597914的博客 1752

GEE APP:基于GEE的红树林监测平台

本文将介绍如何利用Google Earth Engine平台,结合Landsat系列卫星影像和SRTM高程数据,实现红树林分布的动态监测与变化分析。

此星光明博客 160

Java中使用protobuf

Java中使用protobuf

AiFlutter的博客 1461

前端build工程的时候 出现 `build.rollupOptions.external 的解决方法

看到这个Bug,理性分析: 遇到 Rollup failed to resolve import “@vue/devtools-api” 错误可能是由于 Pinia 使用了 @vue/devtools-api 模块,而 Vite 的 Rollup 插件无法解析这个模块 ps:但是我前一秒还可以,加了个别代码,突然不行,我是不相信的 = - =

码农研究僧的博客 3055

protobuf java object_protobuf 与 Java 对象互转

Java使用protobuf时,往往需要在Java对象(比如POJO)和protobuf message的Java对象间互转:protobuf接口需要传入message参数: 把POJO转成message, 作为接口参数;protobuf接口会返回message参数: 需要把message转成POJO, 供后续使用.比如:protobuf的messagemessage HelloRequest {...

weixin_33796288的博客 2411

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Window下Protobuf Java使用教程

Protobuf是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

不忘初心的专栏 3663

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Protobuf】Protobuf快速使用 Java版、Python版

Protobuf介绍。

十一月廿七风雨大作 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Protobuf 之java使用篇

碰巧用到Proto,算是笔记吧算是笔记吧, windows : 1,两个文件:proto.exe,  protobuf-Java-2.4.1.jar 2,建立一个工程TestPb,在下面建立一个proto文件件,用来存放【。proto】文件 3,将proto,exe放在工程下, 4,建立一个msg.proto文件: option java_package = "com.protob

业精于勤荒于嬉;行成于思,毁于随。 4295

protobuf java使用

需要安装protobuf的编译器,然后定义一个protobuf文件 syntax = "proto2"; package com.wq.protobuf; option optimize_for = SPEED; option java_package = "com.wq.protobuf"; option java_outer_classname = "DataInfo"; messag...

wq_wangqiang的博客 3793

protobuf在java中使用_Protobuf系列-2.在Java项目中使用

在上一篇文章中,我们介绍了如何安装Protoc,以及编译一个proto文件.在这篇文章中,我们将会介绍如何在项目中使用这些编译出来的文件.创建一个maven项目通过下面这条命令创建一个最简单的maven项目就好:mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=m...

weixin_29959491的博客 696

java使用protobuf

Java中使用Protobuf Protobuf是Google推出的跨语言的序列化方式,是gRpc中消息的序列化方式。protobuf是高性能的序列化方式,跨语言,序列化后数据尺寸小,序列&amp;amp;反序列化速度快,唯一可能产生的不便就是需要用户编写.proto文件来定义接口和消息格式。 导入jar包 &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;com.googl...

feiying的博客 1039

protobuf java文档_Java中使用Protobuf

gradle依赖库:implementation 'com.google.protobuf:protobuf-java:3.4.0'implementation 'com.google.protobuf:protobuf-java-util:3.4.0'0.编写.proto文件,编译生成对应Java源文件:syntax = "proto2";option java_generic_services...

weixin_42458937的博客 229

protobuf java中的使用

Protobuf在Java中的简单使用   1.      在Java中使用protobuf需要jar包,下载protobuf-Java-2.5.0.jar包文件,添加到项目中。另外需要protoc.exe来编译proto文件。 2.      新建一个msg.proto文件: package com.test.learn;   option java_package = "com.t

u010129251的专栏 1万+

java protobuf 下载_在 Java 中使用 protobuf

在 Java 中使用 protobuf从 https://github.com/google/protobuf/releases 下载编译器,并设置环境变量。创建java项目添加protobuf-java引用compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.2.0'编写.proto文件syntax = ...

weixin_35714577的博客 311

Java 中使用 protobuf

protobuf

y41992910的博客 1611

protobuf for java_ProtoBuf 的java使用

碰巧用到Proto,算是笔记吧算是笔记吧,windows :1,两个文件:proto.exe, protobuf-java-2.4.1.jar2,建立一个工程TestPb,在下面建立一个proto文件件,用来存放【。proto】文件3,将proto,exe放在工程下,4,建立一个msg.proto文件:option java_package = "com.protobuftest.protobu...

weixin_42306480的博客 305

protobuf-java-lite 和 protobuf-java 的区别

这是Protocol Buffers的精简版,也称为,主要用于嵌入式系统和移动设备等资源受限的环境。它去除了protobuf-java中的一些不常用的特性和功能,以减小库的体积并提高性能。:这是Protocol Buffers的Java版本,提供了丰富的API和工具,方便Java开发者使用Protocol Buffers进行数据序列化和反序列化。它支持Java语言的所有特性,并提供了一些额外的功能,如动态消息、反射等。

阿饱同学 1134
上一篇: 【JAVA】synchronized关键字
下一篇: 【JAVA】基于socket的无GUI聊天室
wait_notify
博客等级 码龄10年 3粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值