日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Protobuf学习笔记

發(fā)布時(shí)間:2023/12/2 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Protobuf学习笔记 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Protobuf學(xué)習(xí)筆記

Leave a comment (0)Go to comments

Protocol buffers是什么?

首先了解一下Protocol Buffers(簡(jiǎn)稱ProtoBuf)是什么?官網(wǎng)對(duì)它的定義如下:

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

上述定義描述了Protocol Buffers的全部?jī)?yōu)點(diǎn):語(yǔ)言無(wú)法,平臺(tái)無(wú)關(guān),可擴(kuò)展,用于序列化結(jié)構(gòu)化數(shù)據(jù)。在官方定義之外我認(rèn)為protobuf一種通用結(jié)構(gòu)化組織數(shù)據(jù)描述語(yǔ)言,擁有一整套的簡(jiǎn)單語(yǔ)法規(guī)則,內(nèi)置的類型系統(tǒng)等等。因此在學(xué)習(xí)過(guò)程中,可以把它當(dāng)作一門簡(jiǎn)單的語(yǔ)言來(lái)看待。Protocol Buffers定義了描述文件的結(jié)構(gòu),而描述文件結(jié)構(gòu)的語(yǔ)法檢查,類型檢查則需要protoc來(lái)處理,這時(shí)protoc就是一個(gè)編譯器,在編譯過(guò)程中不但檢查語(yǔ)法還負(fù)責(zé)生成指定格式的目標(biāo)文件。
Protocol Buffers為以.proto文件生成的各種對(duì)象(不限語(yǔ)言)的提供一致的序列化手段,保證數(shù)據(jù)最終持久化后的格式一致。而需要序列化的數(shù)據(jù),由用戶根據(jù).proto文件提供的類,創(chuàng)建相應(yīng)的對(duì)象。

Protobuf的描述文件 proto

在使用Protobuf時(shí),定義描述文件是最重要的事情。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文件結(jié)構(gòu)
    從上面的代碼可以看出,proto文件的結(jié)構(gòu)非常簡(jiǎn)單。
    package java_package 定義生成的java類的package名稱。
    message定義一種類型,類型以Java中的一個(gè)class,book是類名,在生成Java代碼時(shí),就是使用這個(gè)類名。
    接下來(lái)是該類型中包含的字段,字段包括 [限定符 類型 字段名稱 = tag [default = 默認(rèn)值]]
  • protobuf支持的類型
    protobuf支持的默認(rèn)類型如下 .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

除此之外,還支持枚舉,自定義類型等。使用方式見(jiàn)上面代碼示例。更詳細(xì)的介紹見(jiàn)官方文檔
protobuf的自定義類型,支持對(duì)象組合方式,在CPP中使用較少,在Java中廣泛采用,但是目前我們需要序列化的對(duì)象是瘦模型,用不上這種特性。

  • protobuf的限定符
  • required 必填項(xiàng),如果該項(xiàng)不設(shè)值,在序列化時(shí)會(huì)拋出RuntimeException,推薦不使用該字段,該字段一旦使用,無(wú)法更改。不利于以來(lái)的擴(kuò)展
  • optional 不存在時(shí)使用默認(rèn)值,默認(rèn)值可自定義。系統(tǒng)默認(rèn)值如下:int = 0,bool = false,string=”"
  • repeated 類似于Java中的List,在實(shí)際生成Java類時(shí),也是生成一個(gè)List來(lái)表示
  • tag說(shuō)明
    tag 的主要作用是用來(lái)標(biāo)識(shí)每一個(gè)field,序列化時(shí)會(huì)使用tag,取值為數(shù)字。如上面的id = 1,其中的1,即為tag。
    在protobuf序列化encode時(shí)標(biāo)識(shí)每一個(gè)field,0-15比16-少一個(gè)byte,優(yōu)化時(shí)可以使用到。
  • default值
    proto文件中定義的默認(rèn)值在處理版本兼容時(shí)非常有用,下面會(huì)做相關(guān)介紹。
  • guide style
    Protocol Buffers官方提供了一個(gè)Guide Style。其中介紹了一些定義proto的優(yōu)秀實(shí)踐。一句話總結(jié)就是名稱時(shí),message名稱以駝峰方式定義,字段名則需要以如author_name方式定義。字段名在生成Java代碼時(shí),會(huì)自動(dòng)轉(zhuǎn)換為符合Java風(fēng)格的命名方式。

如何在項(xiàng)目中組織proto文件,暫時(shí)能想到下面三種方式:
1、一個(gè)項(xiàng)目中所有的class都在一個(gè)*.proto中定義?
2、每個(gè)class作為單獨(dú)的文件?
3、按模塊劃分.proto文件
目前還沒(méi)有確認(rèn)哪種方式更佳。

Protobuf 生成的對(duì)象及序列化

Protobuf 生成的Java對(duì)象是immutable的,生成后無(wú)法修改,生成的Java對(duì)象以Builder方式構(gòu)建,在調(diào)用Builder時(shí)為field設(shè)值。

  • 序列化方法
    Java接口提供的序列化相關(guān)方法如下: 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.

    在處理序列化及反序列化對(duì)象時(shí),發(fā)現(xiàn)難于對(duì)序列化方法的抽象,因?yàn)樯鲜鰩讉€(gè)方法都不是public的。因此在序列化對(duì)象時(shí),需要針對(duì)每一個(gè)Java對(duì)象實(shí)現(xiàn)其特定的序列化類。

擴(kuò)展問(wèn)題

Protobuf提供了極佳的擴(kuò)展性,在擴(kuò)展時(shí),必須滿足下面的要求:

  • 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).

在擴(kuò)展之后可以實(shí)現(xiàn)下面的世界通
舊的系統(tǒng)可以讀新的數(shù)據(jù),但是無(wú)法讀取到新添加的內(nèi)容
新的系統(tǒng)可以讀舊的數(shù)據(jù),讀不到的新加元素使用默認(rèn)值

?舊數(shù)據(jù)新數(shù)據(jù)舊系統(tǒng)不變忽略新添加的字段新系統(tǒng)不存在的字段取默認(rèn)值,刪除的字段取默認(rèn)值,無(wú)變化
缺點(diǎn):

Protobuf無(wú)疑是一個(gè)非常優(yōu)秀的結(jié)構(gòu)化數(shù)據(jù)序列化協(xié)議,現(xiàn)在我們來(lái)說(shuō)一說(shuō)在Java環(huán)境下,它的一些缺點(diǎn):
1、不支持大數(shù)據(jù)集的處理,少于1M
2、不支持Date,Map這些Java內(nèi)建的對(duì)象

更多詳細(xì)信息請(qǐng)參照官方文件https://developers.google.com/protocol-buffers/docs


總結(jié)

以上是生活随笔為你收集整理的Protobuf学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。