Golang ProtoBuf笔记

什么是protobuf

protobuf(Google Protocol Buffers) 是一套完整的 IDL(接口描述语言),出自Google,基于 C++ 进行的实现,开发人员可以根据 ProtoBuf 的语言规范生成多种编程语言(Golang、Python、Java 等)的接口代码,本篇只讲述 Golang 的基础操作。ProtoBuf 所生成的二进制文件在存储效率上比 XML 高 310 倍,并且处理性能高 12 个数量级,这也是选择 ProtoBuf 作为序列化方案的一个重要因素之一。

项目地址

https://github.com/golang/protobuf

安装protobuf

  1. 直接安装

https://github.com/google/protobuf/releases 下载最新版本。例如 Mac 机器下载 osx 版本

Mac 中默认的 go root 地址为 ++/usr/local/go++,将解压缩出来的 protoc 可执行文件 copy 到 /usr/local/go/bin 下。

执行

1
2
$ protoc --version
# 如果正常打印 libprotoc 的版本信息就表明 protoc 安装成功
1
2
Will:bin zhuangweiming$ protoc --version
libprotoc 3.5.1
  1. 编译安装

    1. https://github.com/google/protobuf/releases 下载最新版本,++protobuf-all-3.5.1.tar.gz++。
    2. 解压缩,在终端执行:tar zxvf protobuf-all-3.5.1.tar.gz
    3. 进入文件目录,在终端执行:cd protobuf-3.5.1/
    4. 执行配置,在终端执行:./configure
    5. 编译,在终端执行:make
    6. 检测编译,在终端执行:make check
    7. 安装 protoc,在终端执行:make install

执行

1
2
Will:bin zhuangweiming$ protoc --version
libprotoc 3.5.1

显示 libprotoc 3.5.1 则为成功。

安装 ProtoBuf 相关的 golang 依赖库。获取 goprotobuf 提供的支持库,包含诸如编码(marshaling)、解码(unmarshaling)等功能。

$ go get -u github.com/golang/protobuf/{protoc-gen-go,proto}

使用

1.创建 protocDemo golang工程

2.在 example 包中编写 person.proto

1
2
3
4
5
6
7
8
9
10
11
syntax = "proto3";
package example;

message person { // aa 会生成 Aa 命名的结构体
int32 id = 1;
string name = 2;
}

message all_person { // aa_bb 会生成 AaBb 的驼峰命名的结构体
repeated person Per = 1;
}

3.进入 Demo 工程的 example 目录,使用 protoc 编译 person.proto

1
2
$ protoc --go_out=. person.proto
# 就会生成 person.pb.go 文件

4.在 golang 工程中使用 protobuf 进行序列化与反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package main

import (
"github.com/golang/protobuf/proto"
"protocDemo/example"
"log"
)

func main() {
// 为 AllPerson 填充数据
p1 := example.Person{
Id:*proto.Int32(1),
Name:*proto.String("xieyanke"),
}

p2 := example.Person{
Id:2,
Name:"gopher",
}

all_p := example.AllPerson{
Per:[]*example.Person{&p1, &p2},
}

// 对数据进行序列化
data, err := proto.Marshal(&all_p)
if err != nil {
log.Fatalln("Mashal data error:", err)
}
println(data)

// 对已经序列化的数据进行反序列化
var target example.AllPerson
err = proto.Unmarshal(data, &target)
if err != nil{
log.Fatalln("UnMashal data error:", err)
}

println(target.Per[0].Name) // 打印第一个 person Name 的值进行反序列化验证
}

console 输出:

1
2
[26/32]0xc4200140e0
xieyanke

参考链接:
https://github.com/google/protobuf