protobuffer在go中的使用

protobuffer在go中的使用

一、采用go mod创建go项目

mkdir protobuf-go
cd protobug-go
go mod init github.com/bobwanglong/protobuf-go

二、安装相关依赖

go get -u github.com/golang/protobuf/protoc-gen-go
touch main.go

三、创建过程

#	创建src文件
mkdir src
cd src
# 创建first文件
mkdir first
cd first
# 创建person.proto文件
touch person.proto

person.proto

syntax = "proto3";

package example.first; //不使用option指定go的包ming,编译后的go包是 “package example_first"
option go_package = "first;firstpb"; // 对编译成的go包重命名为 “package mygo"

message PersonMessage {
    int32 id = 1;
    bool is_adult = 2;
    string name = 3;
    repeated int32 lucky_nums = 4;
}

用protoc编译proto文件

# 此时的位置为 项目根目录
protoc --proto_path src/   --go_out=src/  src/first/person.proto
# 参数说明?
 --proto_path   //proto文件放置的路径
 --go_out=   //编译后输出的go文件放置的位置
 src/first/person.proto  //指定文件

四、调用proto文件生成的内容

在main.go中编写

package main

import (
	"fmt"
	firstpb "github.com/bobwanglong/protobuf-go/src/first"
)

func main() {
	fmt.Println("hello world")
	pm :=NewPersonMessage()
  _= writeToFile("person.bin", pm)
	pm2 :=&firstpb.PersonMessage{}
	_=readFromFile("person.bin",pm2)
	fmt.Println(pm2)
}
func NewPersonMessage() *firstpb.PersonMessage{
	pm := firstpb.PersonMessage{
		Id:        1234,
		IsAdult:   true,
		Name:      "bob",
		LuckyNums: []int32{1, 2, 3, 4},
	}
	fmt.Println(pm)
	pm.Name = "Nick"
	fmt.Println(pm)

	fmt.Printf("Id is %d\n",pm.GetId())
}


将protobuf中的信息写入文件

// 写入文件
func writeToFile(fileName string, pb proto.Message)error  {
	dataBytes,err :=proto.Marshal(pb)
	if err !=nil{
		log.Fatalln("无法序列化到bytes")
	}
	if err =ioutil.WriteFile(fileName,dataBytes,0644);err !=nil{
		log.Fatalln("无法写入到文件",err.Error())
	}
	log.Println("成功写入文件")
	return nil
}
//从文件中读取
func readFromFile(fileName string, pb proto.Message)error  {
	dataBytes,err :=ioutil.ReadFile(fileName)
	if err !=nil{
		log.Fatalln("read wrong",err.Error())
	}
	err = proto.Unmarshal(dataBytes,pb)
	if err !=nil{
		log.Fatalln("转化为struct的时候发生错误",err.Error())
	}
	return nil
}

写入jison和读取json

func toJson(pb proto.Message) string {
	marshaler := jsonpb.Marshaler{Indent:"	"} //Indent 缩进格式
	str,err :=marshaler.MarshalToString(pb)
	if err !=nil{
		log.Fatalln("json序列化失败",err.Error())
	}
	return str
}

func fromJson(in string, pb proto.Message)error  {
	err :=jsonpb.UnmarshalString(in,pb)
	if err !=nil{
		log.Fatalln("读取json时发生错误",err.Error())
	}
	return nil
}

调用

// 需要引入的包
import ""github.com/golang/protobuf/jsonpb""
func main(){
  //调用
  pm := NewPersonMessage()
  pmStr :=toJson(pm)
	fmt.Println(pmStr)
	pm3:=&firstpb.PersonMessage{}
	_=fromJson(pmStr,pm3)
	fmt.Println("pb struct:",pm3)
}

输出

# json序列化结果
{
	"id": 1234,
	"isAdult": true,
	"name": "Nick",
	"luckyNums": [
		1,
		2,
		3,
		4
	]
}
# json反序列化为pb struct
pb struct: id:1234 is_adult:true name:"Nick" lucky_nums:1 lucky_nums:2 lucky_nums:3 lucky_nums:4

针对复合类型的生成

//新建一个complexpb.proto,位置在src/third文件夹
syntax = "proto3";

package example.third;

option go_package = "third;complexpb";

message DepartmentMessage{
    int32 id = 1;
    string name = 2;
    repeated EmployeeMessage employees = 3;
    DepartmentMessage parent_department = 4;
    repeated DepartmentMessage children_departments = 5;
}

message EmployeeMessage{
    int32 id = 1;
    string name = 2;
}

main.go中编写调用

//引入
import (
complexpb "protobuf-go/src/third"
)

  // 复合类型
func NewDepartmentMessage() *complexpb.DepartmentMessage {
	dm := &complexpb.DepartmentMessage{
		Id:   1234,
		Name: "开发部",
		Employees: []*complexpb.EmployeeMessage{
			&complexpb.EmployeeMessage{
				Id:   12,
				Name: "Dave",
			},
			&complexpb.EmployeeMessage{
				Id:   34,
				Name: "Mike",},
		},
		ParentDepartment: &complexpb.DepartmentMessage{
			Id:   1211,
			Name: "总公司",},
		ChildrenDepartments: nil,
	}
	return dm
}
func main(){
    dm :=NewDepartmentMessage()
		fmt.Println(dm)
  }
// 输出结果
id:1234  name:"开发部"  employees:{id:12  name:"Dave"}  employees:{id:34  name:"Mike"}  parent_department:{id:1211  name:"总公司"}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值