Protobuf与GO 关于协议缓冲区,数据格式,以及如何实现的教程

作者 : IT 大叔 本文共3579个字,预计阅读时间需要9分钟 发布时间: 2020-09-22

在本文中,我们将了解什么是协议缓冲区,数据格式以及如何在基于Go应用程序中实现它。

什么是协议缓冲区?

协议缓冲区是一种数据格式,例如JSON和XML,它存储可以序列化和反序列化的结构化数据。它是Google开发的一种数据格式。Protobuf的主要优点是它比其他格式小得多。

Protobuf比XML小3到10倍,快20到100倍。

现在,让我们进行一场足球比赛,并以XML,JSON和Protobuf表示数据。

XML:

<game>
  <home>Real Madrid</home>
  <away>Barcelona</away>
  <venue>Santiago Bernabéu Stadium</venue>
  <date>26-10-2019</date>
</game>

JSON:

{
  "home": "Real Madrid",
  "away": "Barcelona",
  "venue": "Santiago Bernabéu Stadium",
  "date": "26-10-2019"
}

Protobuf:

[10 11 82 101 97 108 32 77 97 100 114 105 100 18 9 66 97 114 99 101 108 111 110 97 26 26 83 97 110 116 105 97 103 111 32 66 101 114 110 97 98 195 169 117 32 83 116 97 100 105 117 109 34 10 50 54 45 49 48 45 50 48 49 57]

上面显示的protobuf格式是字符串的编码字节,从数组的位置2开始。字符串“ Real Madrid”的拼写为:R = 82,e = 101,依此类推。

要了解这种编码,请在此处查看Google自己的文档:Proton Buffer Encoding

在这个规模上,大小几乎是相似的。但是,当我们将其缩放到更大的数据时,大小开始显示出巨大的差异。

因此,现在让我们将Protobuf带入我们的Go代码。

安装套件

  go_workspace go get github.com/golang/protobuf
  go_workspace go get github.com/golang/protobuf/proto
  go_workspace go get -u github.com/golang/protobuf/protoc-gen-go
  go_workspace export PATH=$PATH:$GOPATH/bin

这将安装必要的程序包,我们现在准备就绪。

现在,让我们为游戏对象定义protobuf。

Game.proto

syntax = "proto3";

package main;

message Game {
  string home = 1;
  string away = 2;
  string venue = 3;
  string date = 4;
}

我们首先指定proto的版本语法。在这里,我们将语法设置为“ proto3”。接下来,我们定义要在其中使用该对象的包。之后,我们将定义游戏对象的格式。这由我们类型为Game的消息格式组成,该消息格式具有以下字段,家庭,离开,地点和日期。

定义原始文件时,我们将使用该原始文件进行编译。

  go_workspace/src protoc --go_out=. *.proto

这将生成一个game.pb.go文件,该文件具有自动生成的代码。要详细了解此代码,请查看Google文档:转到生成的代码

main.go

package main
import (
  fmt "fmt"
  "log"
  proto "github.com/golang/protobuf/proto"
)
func main() {
  elClasico := &Game{
    Home:  "Real Madrid",
    Away:  "Barcelona",
    Venue: "Santiago Bernabéu Stadium",
    Date:  "26-10-2019",
  }
  data, err := proto.Marshal(elClasico)
  if err != nil {
    log.Fatal("Marshaling error: ", err)
  }
  fmt.Println(data)
  newElClasico := &Game{}
  err = proto.Unmarshal(data, newElClasico)
  if err != nil {
    log.Fatal("UnMarshaling error: ", err)
  }
  fmt.Println(newElClasico.GetHome())
  fmt.Println(newElClasico.GetAway())
  fmt.Println(newElClasico.GetVenue())
  fmt.Println(newElClasico.GetDate())
}

在上面的代码中,我们使用game.pb.go中定义的Game结构将详细信息添加到elClasico对象。我们使用原型库的Marshal函数将对象转换为Protobuf格式。然后可以使用Unmarshal函数对编码的字节进行解码。现在,我们可以使用在game.pb.go文件中生成的GetHome,GetAway函数从解码后的对象获取值。

  go_workspace/src go run main.go game.pb.go
[10 11 82 101 97 108 32 77 97 100 114 105 100 18 9 66 97 114 99 101 108 111 110 97 26 26 83 97 110 116 105 97 103 111 32 66 101 114 110 97 98 195 169 117 32 83 116 97 100 105 117 109 34 10 50 54 45 49 48 45 50 48 49 57]
Home:  Real Madrid
Away:  Barcelona
Venue:  Santiago Bernabéu Stadium
Date:  26-10-2019

不要忘了包括game.pb.go。现在,我们有一个小例子并开始运行。但是实际上,在现实世界中,数据不会变得如此简单。现在,让我们看看一些嵌套字段。

我们将使用相同的Game对象。在这种情况下,我们将田野带回家,并使其成为一个团队对象。

game.proto:

syntax = "proto3";
package main;
message Team {
  string home = 1;
  string away = 2;
}
message Game {
  Team team = 1;
  string venue = 2;
  string date = 3;
}

同样,我们创建自动生成的代码。

  go_workspace/src protoc --go_out=. *.proto

然后,我们将相应地更新main.go文件。

main.go

package main
import (
  fmt "fmt"
  "log"
  proto "github.com/golang/protobuf/proto"
)
func main() {
  elClasico := &Game{
    Venue: "Santiago Bernabéu Stadium",
    Date:  "26-10-2019",
    Team: &Team{
      Home: "Real Madrid",
      Away: "Barcelona",
    },
  }
  data, err := proto.Marshal(elClasico)
  if err != nil {
    log.Fatal("marshaling error: ", err)
  }
  fmt.Println(data)
  newElClasico := &Game{}
  err = proto.Unmarshal(data, newElClasico)
  if err != nil {
    log.Fatal("unmarshaling error: ", err)
  }
  fmt.Println("Home: ", newElClasico.Team.GetHome())
  fmt.Println("Away: ", newElClasico.Team.GetAway())
  fmt.Println("Venue: ", newElClasico.GetVenue())
  fmt.Println("Date: ", newElClasico.GetDate())
}

现在,如果我们运行该程序。

  go_workspace/src go run main.go game.pb.go
[10 24 10 11 82 101 97 108 32 77 97 100 114 105 100 18 9 66 97 114 99 101 108 111 110 97 18 26 83 97 110 116 105 97 103 111 32 66 101 114 110 97 98 195 169 117 32 83 116 97 100 105 117 109 26 10 50 54 45 49 48 45 50 48 49 57]
Home:  Real Madrid
Away:  Barcelona
Venue:  Santiago Bernabéu Stadium
Date:  26-10-2019

有趣,不是吗?

好的,我们现在知道如何在Go中使用协议缓冲区数据格式。现在就这样。

免责声明:
1. 本站资源转自互联网,源码资源分享仅供交流学习,下载后切勿用于商业用途,否则开发者追究责任与本站无关!
2. 本站使用「署名 4.0 国际」创作协议,可自由转载、引用,但需署名原版权作者且注明文章出处
3. 未登录无法下载,登录使用金币下载所有资源。
IT小站 » Protobuf与GO 关于协议缓冲区,数据格式,以及如何实现的教程

常见问题FAQ

没有金币/金币不足 怎么办?
本站已开通每日签到送金币,每日签到赠送五枚金币,金币可累积。
所有资源普通会员都能下载吗?
本站所有资源普通会员都可以下载,需要消耗金币下载的白金会员资源,通过每日签到,即可获取免费金币,金币可累积使用。

发表评论