写在前面
protobuf是Google开发的一种数据描述语言,能够将结构化的数据序列化,可用于数据存储,通信协议等方面,官方版本支持 Go, C++, Java, Python,社区版本支持更多语言.
相对于JSON和XML具有以下优点:
体积小: 消息大小只需要XML的1/10 ~ 1⁄3
速度快: 解析速度比XML快20 ~ 100倍
集成度高: 使用Protobuf的编译器,可以生成更容易在编程中使用的数据访问代码
更好的兼容性: Protobuf设计的一个原则就是要能够很好地向下或向上兼容
安装
1.从 https://github.com/google/protobuf/releases 获取 Protobuf 编译器 protoc
wget https://github.com/google/protobuf/releases/download/v3.6.1/protobuf-all-3.6.1.tar.gz
tar zxvf protobuf-all-3.6.1.tar.gz
cd protobuf-3.6.1
./configure
make
make install
protoc -h
protoc --version
遇到的问题及解决方案
[1] libprotoc.so.17: cannot open shared object file: No such file or directory
bjlvxin:~/下载/protobuf-3.6.1$ protoc --version
protoc: error while loading shared libraries: libprotoc.so.17: cannot open shared object file: No such file or directory
解决方案:执行:export LD_LIBRARY_PATH=/usr/local/lib
bjlvxin:~/下载/protobuf-3.6.1$ export LD_LIBRARY_PATH=/usr/local/lib/
bjlvxin:~/下载/protobuf-3.6.1$ protoc --version
libprotoc 3.6.1
2.获取 goprotobuf 提供的 Protobuf 插件 protoc-gen-go(被放置于 $GOPATH/bin 下,$GOPATH/bin 应该被加入 PATH 环境变量,以便 protoc 能够找到 protoc-gen-go)
此插件被 protoc 使用,用于编译 .proto 文件为 Golang 源文件,通过此源文件可以使用定义在 .proto 文件中的消息。
go get github.com/golang/protobuf/protoc-gen-go
cd $GOPATH/src/github.com/golang/protobuf/protoc-gen-go
go build
go install
vi ~/.bashrc 将$GOPATH/bin 加入环境变量:export PATH=$PATH:$GOPATH/bin
source ~/.bashrc
3.获取 goprotobuf 提供的支持库,包含诸如编码(marshaling)、解码(unmarshaling)等功能
go get github.com/golang/protobuf/proto
cd $GOPATH/src/github.com/golang/protobuf/proto
go build
go install
使用
本文通过golang对protobuf进行使用。
1.通过GoLand创建一个新的golang工程:
2.在 example 包中编写 person.proto
syntax = "proto3";
package example;
// person 会生成 Person 命名的结构体
message person {
int32 id = 1;
string name = 2;
}
// all_person 会按照驼峰规则自动生成名为AllPerson 的结构体
message all_person {
repeated person Per = 1;
}
3.进入 protobuf-golang 工程的 proto 目录,使用 protoc 编译 person.proto
protoc --go_out=. person.proto
执行完毕后会在proto目录下生成对应的go文件:person.pb.go
4.编写工程的main.go文件:
/*
Copyright 2018 JD-Tiger
created by lvxin at 18-8-13 下午12:03
*/
package main
import (
example "github.com/lvxin1986/protobuf-golang/proto"
"log"
"github.com/golang/protobuf/proto"
"fmt"
)
func main() {
// 为 AllPerson 填充数据
//使用protobuf的封装类型定义
p1 := example.Person{
Id:*proto.Int32(1),
Name:*proto.String("lvxin"),
}
//使用golang的原始类型定义
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)
}
// 对已经序列化的数据进行反序列化
var target example.AllPerson
err = proto.Unmarshal(data, &target)
if err != nil{
log.Fatalln("UnMashal data error:", err)
}
for k,v := range target.Per {
fmt.Println("person[",k,"]:",v.Name)
}
}
5.开发完毕后直接运行:
6.运行结果如下:
GOROOT=/software/servers/go1.10.3 #gosetup
GOPATH=/sourcecode/go/work #gosetup
/software/servers/go1.10.3/bin/go build -i -o /tmp/___go_build_main_go /sourcecode/go/work/src/github.com/lvxin1986/protobuf-golang/main.go #gosetup
/tmp/___go_build_main_go #gosetup
person[ 0 ]: lvxin
person[ 1 ]: gopher
Process finished with exit code 0
打完收工。
参考文献
https://www.jianshu.com/p/1a3f1c3031b5
https://segmentfault.com/a/1190000010477733
http://lihaoquan.me/2017/6/29/how-to-use-protobuf.html
https://www.pythonxyz.com/10038-install-protobuf-in-ubuntu.xyz
有疑问加站长微信联系(非本文作者)