protobuf数据类型byte_protobuf的使用特性及编码原理

本文深入探讨了Protocol Buffer(protobuf)的使用特性与编码原理。第一部分介绍了protobuf的字段转换兼容性、序号重要性及其对编码大小的影响、模型字段数据类型兼容性以及protobuf与JSON的转换和对比。第二部分揭示了protobuf的varints编码方式,并通过实例解析protobuf的编码过程,强调了序号在protobuf编码中的关键作用。
摘要由CSDN通过智能技术生成

这一系列文章主要是对protocol buffer这种编码格式的使用方式、特点、使用技巧进行说明,并在原生protobuf的基础上进行扩展和优化,使得它能更好地为我们服务。

在上一篇文章中

google protocol buffer——protobuf的基本使用和模型分析

我们展示了protobuf在java中的基本使用方式。而本文将继续深入探究protobuf的编码原理。

主要分为两个部分

第一部分是结合上一篇文章留下的几个伏笔展示protobuf的使用特性

第二部分是分析protobuf的编码原理,解释特性背后的原因

第一部分,Protobuf使用特性

1.不同类型对象的转换

我们先定义如下一个.proto文件

syntax = "proto3";option java_package = "cn.tera.protobuf.model";option java_outer_classname = "DifferentModels";message Person {
      string name = 1;  int32 id = 2;  string email = 3;}message Article {
      string title = 1;  int32 wordsCount = 2;  string author = 3;}

其中我们定义了2个模型,一个Person,一个Article,虽然他们的字段名字不相同,但是类型和编号都是一致的

接着我们生成.java文件,最终文件结构如下图

3d40100312170b27cdb53ca1f4003297.png

此时我们尝试做如下的一个转换

/** * 测试不同模型间的转换 * @throws Exception */@Testpublic void parseDifferentModelsTest() throws Exception {
        //创建一个Person对象    DifferentModels.Person person = DifferentModels.Person.newBuilder()            .setName("person name")            .setId(1)            .setEmail("tera@google.com")            .build();    //对person编码    byte[] personBytes = person.toByteArray();    //将编码后的数据直接merge成Article对象    DifferentModels.Article article = DifferentModels.Article.parseFrom(personBytes);    System.out.println("article's title:" + article.getTitle());    System.out.println("article's wordsCount:" + article.getWordsCount());    System.out.println("article's author:" + article.getAuthor());}

输出结果如下

article's title:person namearticle's wordsCount:1article's author:tera@google.com

可以看到,虽然jsonBytes是由person对象编码得到的,但是可以用于article对象的解码,不但不会报错,所有的数据内容都是完整保留的

这种兼容性的前提是模型中所定义的字段类型和序号都是一一对应相同的

在平时的编码中,我们经常会遇到从数据库中读取数据模型,然后将其转换成业务模型,而很多时候,这2种模型的内容其实是完全一致的,此时我们也许就可以使用protobuf的这种特性,就可以省去很多低效的赋值代码

2.protobuf序号的重要性

在上一篇文章中,我们看到在定义.proto文件时,字段后面会跟着一个"= X",这里并不是指这个字段的值,而是表示这个字段的“序号”,和正确地编码与解码息息相关,在我看来是protocol buffer的灵魂

我们定义如下的.proto文件,这里注意,Model1和Model2的name和id的序号有不同

syntax = "proto3";option java_package = "cn.tera.protobuf.model";option java_outer_classname = "TagImportance";message Model1 {
      string name = 1;  int32 id = 2;  string email = 3;}message Model2 {
      string name = 2;  int32 id = 1;  string email = 3;}

定义如下的测试方法

/** * 序号的重要性测试 * * @throws Exception */@Testpublic void tagImportanceTest() throws Exception {
        TagImportance.Model1 model1 = TagImportance.Model1.newBuilder()            .setEmail("model1@google.com")            .setId(1)            .setName("model1")            .build
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值