马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
Go 语言使用Protobuf 举行序列化详解
1. Protobuf是什么?
以下是 Protobuf 官方中文文档的概述:
Protobuf(Protocol Buffers) 是一种语言中立、平台中立的可扩展机制,用于序列化结构化数据。
它类似于 JSON,但更小、更快,而且天生本机语言绑定。您只需界说一次数据结构,然后可以使用特殊天生的源代码轻松地将结构化数据读写到各种数据流中,并使用各种语言。
Protocol buffers 是界说语言(在 .proto 文件中创建)、proto 编译器天生的用于与数据交互的代码、特定于语言的运行时库、写入文件(或通过网络毗连发送)的数据的序列化格式以及序列化数据的组合。
相比力传统的传输协议, 其以紧凑的二进制格式举行传输, 对比 json,xml等文本格式能显着镌汰数据体积, 对比文本格式通常小3-10倍, 低落网络传输开销。
尤其是在序列化方面,得益于二进制数据无需文本剖析, 处置处罚速率更快,得当高性能场景。
2. 安装Protobuf 及 Go 依赖
使用 Protobuf 必要 Protobuf 编译器, 安装方法如下:
windows下载链接
在情况变量中参加Protobuf bin 目次
Linux下载方法:
- wget https://github.com/protocolbuffers/protobuf/releases/download/v30.0/protoc-30.0-linux-x86_64.zip
- unzip protoc-30.0-linux-x86_64.zip -d /usr/local/
复制代码 下载完成后输入
- protoc --version
- libprotoc 30.0 # 出现此行表示安装成功
复制代码 安装 go protobuf 插件
- go get -u google.golang.org/grpc
复制代码 3. 编写.proto 文件
- syntax = "proto3"; // 声明 protobuf 编译器版本
- package Marshal; // 声明包
- option go_package = "./Marshal"; // 声明生成 .pd.go 文件的路径 此处表示在当前目录中的 Marshal 目录中
- // 声明一个消息类型
- // 字段使用键值对的方式定义, 以 类型 字段名 唯一编号进行定义, 该编号用来在二进制格式消息中识别字段
- message User{
- int64 id = 1;
- string name = 2;
- string sex = 3;
- float money = 4;
- bool is_vip = 5;
- repeated string tags = 6; // 数组类型
- map<string, string> info = 7; // map类型
- message Phone{ // 嵌套类型
- string num1 = 1;
- string num2 = 2;
- }
- Phone phone = 8; // 嵌套类型需声明为一个字段才能使用
- }
复制代码 4. 实现序列化和反序列化
使用 protobuf 编译器根据 .proto 文件天生对应的 .pb.go 文件
- protoc --go_out=. --go-grpc_out=. protoFileName.proto
复制代码 实现序列化和反序列化
- import (
- pd "Marshal/protobuf/Marshal" // 导入生成的 .pb.go 文件
- f "fmt"
- "google.golang.org/protobuf/proto" // 导入 proto 包
- )
- func main() {
- // 定义 生成消息对应的结构体对象
- user1 := &pd.User{
- Id: 1001,
- Name: "Tom",
- Sex: "man",
- Money: 100,
- IsVip: false,
- Tags: []string{"football", "games", "music"},
- Info: map[string]string{"age": "18", "passwd": "000000"},
- Phone: &pd.User_Phone{
- Num1: "10086",
- Num2: "10000",
- },
- }
- user2 := pd.User{}
- // 使用 proto 包中的 Marshal 方法对 user1 进行序列化
- data, err := proto.Marshal(user1)
- if err != nil {
- f.Println(err)
- }
- f.Printf("二进制数据大小:%d bytes\n", len(data))
- // 使用 proto 包中的 UnMarshal 方法对 user2 进行反序列化, 将数据反序列化进 user2
- err = proto.Unmarshal(data, &user2)
- if err != nil {
- f.Println(err)
- }
- f.Println(user2)
- }
复制代码 |