Protobuf学习笔记

Protobuf学习笔记

Protocol buffers是什么?

首先了解一下Protocol Buffers(简称ProtoBuf)是什么?官网对它的定义如下:

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler.

上述定义描述了Protocol Buffers的全部优点:语言无法,平台无关,可扩展,用于序列化结构化数据。在官方定义之外我认为protobuf一种通用结构化组织数据描述语言,拥有一整套的简单语法规则,内置的类型系统等等。因此在学习过程中,可以把它当作一门简单的语言来看待。Protocol Buffers定义了描述文件的结构,而描述文件结构的语法检查,类型检查则需要protoc来处理,这时protoc就是一个编译器,在编译过程中不但检查语法还负责生成指定格式的目标文件。
Protocol Buffers为以.proto文件生成的各种对象(不限语言)的提供一致的序列化手段,保证数据最终持久化后的格式一致。而需要序列化的数据,由用户根据.proto文件提供的类,创建相应的对象。

Protobuf的描述文件 proto

在使用Protobuf时,定义描述文件是最重要的事情。Protobuf描述文件格式如下:

/*** Created by IntelliJ IDEA.* User: huxing(xing.hu@360hqb.com)* Date: 12-5-22* Time: 下午2:22*/
package org.colorfuldays.ssm.domain.protobuf;option java_package = "org.colorfuldays.ssm.domain.protobuf";message User{optional int64 id = 1;optional string name = 2;optional string password = 3;
}message book{optional int64 id = 1;optional string name = 2;optional string isbn = 3;repeated User author = 4;optional int64 publish_date = 5;
}
  • proto文件结构
    从上面的代码可以看出,proto文件的结构非常简单。
    package java_package 定义生成的java类的package名称。
    message定义一种类型,类型以Java中的一个class,book是类名,在生成Java代码时,就是使用这个类名。
    接下来是该类型中包含的字段,字段包括 [限定符 类型 字段名称 = tag [default = 默认值]]
  • protobuf支持的类型
    protobuf支持的默认类型如下
    .proto TypeNotesC++ TypeJava Type
    double doubledouble
    float floatfloat
    int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32int
    int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64long
    uint32Uses variable-length encoding.uint32int1
    uint64Uses variable-length encoding.uint64long1
    sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32int
    sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64long
    fixed32Always four bytes. More efficient than uint32 if values are often greater than 228.uint32int1
    fixed64Always eight bytes. More efficient than uint64 if values are often greater than 256.uint64long1
    sfixed32Always four bytes.int32int
    sfixed64Always eight bytes.int64long
    bool boolboolean
    stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringString
    bytesMay contain any arbitrary sequence of bytes.stringByteString

除此之外,还支持枚举,自定义类型等。使用方式见上面代码示例。更详细的介绍见官方文档
protobuf的自定义类型,支持对象组合方式,在CPP中使用较少,在Java中广泛采用,但是目前我们需要序列化的对象是瘦模型,用不上这种特性。

  • protobuf的限定符
  • required 必填项,如果该项不设值,在序列化时会抛出RuntimeException,推荐不使用该字段,该字段一旦使用,无法更改。不利于以来的扩展
  • optional 不存在时使用默认值,默认值可自定义。系统默认值如下:int = 0,bool = false,string=”"
  • repeated 类似于Java中的List,在实际生成Java类时,也是生成一个List来表示
  • tag说明
    tag 的主要作用是用来标识每一个field,序列化时会使用tag,取值为数字。如上面的id = 1,其中的1,即为tag。
    在protobuf序列化encode时标识每一个field,0-15比16-少一个byte,优化时可以使用到。
  • default值
    proto文件中定义的默认值在处理版本兼容时非常有用,下面会做相关介绍。
  • guide style
    Protocol Buffers官方提供了一个Guide Style。其中介绍了一些定义proto的优秀实践。一句话总结就是名称时,message名称以驼峰方式定义,字段名则需要以如author_name方式定义。字段名在生成Java代码时,会自动转换为符合Java风格的命名方式。

如何在项目中组织proto文件,暂时能想到下面三种方式:
1、一个项目中所有的class都在一个*.proto中定义?
2、每个class作为单独的文件?
3、按模块划分.proto文件
目前还没有确认哪种方式更佳。

Protobuf 生成的对象及序列化

Protobuf 生成的Java对象是immutable的,生成后无法修改,生成的Java对象以Builder方式构建,在调用Builder时为field设值。

  • 序列化方法
    Java接口提供的序列化相关方法如下:
    byte[] toByteArray();: serializes the message and returns a byte array containing its raw bytes.
    static Person parseFrom(byte[] data);: parses a message from the given byte array.
    void writeTo(OutputStream output);: serializes the message and writes it to an OutputStream.
    static Person parseFrom(InputStream input);: reads and parses a message from an InputStream.

    在处理序列化及反序列化对象时,发现难于对序列化方法的抽象,因为上述几个方法都不是public的。因此在序列化对象时,需要针对每一个Java对象实现其特定的序列化类。

扩展问题

Protobuf提供了极佳的扩展性,在扩展时,必须满足下面的要求:

  • you must not change the tag numbers of any existing fields.
  • you must not add or delete any required fields.
  • you may delete optional or repeated fields.
  • you may add new optional or repeated fields but you must use fresh tag numbers (i.e. tag numbers that were never used in this protocol buffer, not even by deleted fields).

在扩展之后可以实现下面的世界通
旧的系统可以读新的数据,但是无法读取到新添加的内容
新的系统可以读旧的数据,读不到的新加元素使用默认值

 旧数据新数据
旧系统不变忽略新添加的字段
新系统不存在的字段取默认值,删除的字段取默认值,无变化
缺点:

Protobuf无疑是一个非常优秀的结构化数据序列化协议,现在我们来说一说在Java环境下,它的一些缺点:
1、不支持大数据集的处理,少于1M
2、不支持Date,Map这些Java内建的对象

更多详细信息请参照官方文件https://developers.google.com/protocol-buffers/docs


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何掌握Java内存(并保存程序)

通过AppDynamics解决应用程序问题的速度提高了10倍–以最小的开销在代码级深度监视生产应用程序。 开始免费试用! 您花了无数小时来研究Java应用程序中的错误并在需要的地方获得其性能。 在测试期间,您注意到应用程序随着时间的推移逐渐变慢&#xff0c…

程序集版本号

程序集版本号分为4段,例如1.0.4.23。 第一段为主版本号,项目一但启动则不会更改。 第二段为次版本号,在项目功能做较大调整时增加,增量为1。 第三段为修订版本号,通常在解决缺陷或者细微功能变化时增加,增量…

py-kms使用方法

搭建py-kms服务器,先下载py-kms https://github.com/myanaloglife/py-kms 启动py-kms服务(需要服务器安装有python): python server.py 这样py-kms服务就启动好了,如果需要后台运行可以制作deamon脚本。 py-kms可以激活企业/专业版vl windows系统和vol版本的office软件: window…

JAVA泛型--待续

原做法&#xff1a; Map m new HashMap();m.put("key", "blarg");String s (String) m.get("key"); 泛型做法&#xff1a; Map<K,V> m new HashMap()<K,V>;m.put("key", "blarg");//非<K,V>类型无法操…

Tortoise SVN 版本控制常用操作知识

Tortoise SVN 版本控制常用操作知识 Posted on 2010-11-26 23:07 szh114 阅读(5897) 评论(0) 编辑 收藏 今天老大跑过来问我如何把SVN服务器上的当前版本回退到某一个版本上去&#xff0c;我没回答上来&#xff0c;很失败&#xff0c;所以现在整理一下Tortoise SVN的操作知识&…

如何导入任何JBoss BRMS示例项目

在过去几周内&#xff0c;JBoss BRMS演示的用户反复询问我以下内容时&#xff0c;会给您这些提示和技巧&#xff1a; “如何将与各种JBoss BRMS演示项目相关的项目导入到我自己的现有安装中&#xff1f;” 这意味着用户希望在产品的个人安装中有一个示例项目&#xff0c;而无…

2110: 扫雷

http://acm.zcmu.edu.cn/JudgeOnline/problem.php?id2110 2110: 扫雷 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 88 Solved: 36[Submit][Status][Web Board]Description 扫雷游戏你一定玩过吧&#xff01;现在给你若干个nm的地雷阵&#xff0c;请你计算出每个矩阵中每…

使用eclipse生成文档(javadoc)

使用eclipse生成文档&#xff08;javadoc&#xff09;主要有三种方法&#xff1a; 1&#xff0c;在项目列表中按右键&#xff0c;选择Export&#xff08;导出&#xff09;&#xff0c;然后在Export(导出)对话框中选择java下的javadoc&#xff0c;提交到下一步。 在Javadoc Gene…

青椒苗

转载于:https://www.cnblogs.com/wainiwann/p/8793418.html

更改日志级别_如何在运行时更改日志记录级别

更改日志级别在运行时中更改日志记录级别非常重要&#xff0c;这主要在生产环境中非常重要&#xff0c;在生产环境中&#xff0c;您可能希望在有限的时间内进行调试日志记录。 好了&#xff0c;更改根记录器非常简单–假设您有一个具有所需记录级别的输入参数&#xff0c;只需…

JDBC和Ibatis中的Date,Time,Timestamp处理

JDBC和Ibatis中的Date,Time,Timestamp处理 November 25th, 2010西坪 Leave a commentGo to comments在此前&#xff0c;遇到过使用Ibatis操作Oracle时时间精度丢失的问题&#xff0c;昨天又遇到JDBC操作MySQL时间字段的问题&#xff0c;从网上看到各种式样的解释这些问题的博文…

每日算法之抽签

X星球要派出一个5人组成的观察团前往W星。其中&#xff1a;A国最多可以派出4人。B国最多可以派出2人。C国最多可以派出2人。....那么最终派往W星的观察团会有多少种国别的不同组合呢&#xff1f;下面的程序解决了这个问题。数组a[] 中既是每个国家可以派出的最多的名额。程序执…

如何开始Java机器学习

什么是开始使用Java机器学习的最佳工具&#xff1f; 他们已经存在了一段时间&#xff0c;但如今看来&#xff0c;每个人都在谈论人工智能和机器学习。 对于科学家和研究人员而言&#xff0c;它已不再是秘密&#xff0c;几乎可以在任何新兴技术中实现。 在下面的文章中&#x…

keil中关于使用_at_绝对地址定位问题

keil中关于使用_at_绝对地址定位问题 2008-01-07 13:46:26| 分类&#xff1a; MCU51 | 标签&#xff1a; |字号大中小 订阅 在网上看到有人提到在keil中使用_at_进行绝对地址定位问题&#xff0c;我简单介绍一下它的用法。 使用_at_关键字对存储器进行绝对地址定位程序…

ztree树

常规的ztree树 后台数据封装成list对象 public PageModel getTreeBuildingRegData(Map<String, String> params) {PageModel pageModelnew PageModel();String statusparams.get("status");String orgIdparams.get("org_id");List<OmsBuildingReg…

如何提高效率

如何提高效率 时间管理 April 28th, 2011 本文来自读者 桃雨 翻译投稿。 Aaron Swartz写过一篇很有名的文章&#xff0c;叫做《HOWTO: Be more productive》&#xff08;如何提高效率&#xff09;。这篇文章写的实在是太好了&#xff0c;我看了好多遍&#xff0c;很赞同作者的…

Andrew Ng - 深度学习工程师 - Part 2. 改善深层神经网络:超参数调试、正则化以及优化(Week 1. 机器学习的实用层面)...

第1周 机器学习的实用层面 1.1 训练/开发/测试 早期机器学习时代&#xff08;数据规模较小&#xff09;&#xff0c;如果不需要dev set&#xff0c;常见的划分有 70%/30% 的训练/测试 划分&#xff0c;如果需要验证集&#xff0c;常见的是 60%/20%/20%划分 在big data era&…

jms 如何测试_使用JMSTester对JMS层进行基准测试

jms 如何测试对于我去过的大多数客户端&#xff0c;使用ActiveMQ扩展JMS消息传递层是一个优先事项。 有多种方法可以实现这一目标&#xff0c;但毫无疑问&#xff0c;创建基准并分析实际硬件上的体系结构&#xff08;或者正如我的同事Gary Tully所说的“询问机器”&#xff09;…

为什么待办事项清单不管用

为什么待办事项清单不管用 时间管理 November 22nd, 2012 本文原文来自 Harvard Business Review&#xff0c;由 换装迷宫tayy 翻译。 停止制作你的待办事项清单吧。它们只会让你感觉失败和受挫。想想你正在管理的那些待办清单&#xff1a;有多少事项从年初起就已经在那儿了&…

charts 画饼图

统计某一天某类物体的百分比 新知识点&#xff1a;aggregate https://blog.csdn.net/congcong68/article/details/51619882 主要的 $group $match $sort $limit pipeline [{$group:{_id:$area,count:{$sum:1}}}, # count 是聚合之后新增的一个字段。{$sort:{count:1}}, # …