golang使用protobuf简易教程
2017-11-02 15:08
591 查看
golang使用protobuf简易教程
google公司发布的一套开源编码规则,基于二进制流的序列化传输,可以转换成多种编程语言,几乎涵盖了市面上所有的主流编程语言,当然也包括Go1、安装protobuf
安装下载protoc,很多种安装方法,下载地址https://github.com/google/protobuf/releases
安装下载proto的go插件,命令是
go get github.com/golang/protobuf/protoc-gen-go,也可以自己手动下载安装(如果使用go get则会自动生成protoc-gen-go的可执行文件)
将protoc-gen-go可执行文件路径加到PATH环境变量中,如果是go get安装是会在GOBIN路径下生成protoc-gen-go,执行
export PATH=$PATH:$GOBIN(原因在于, protoc-gen-go可执行文件需要被protoc调用)
安装goprotobuf库(注意,protoc-gen-go只是一个插件,goprotobuf的其他功能比如marshal、unmarshal等功能还需要由protobuf库提供)
go get github.com/golang/protobuf/proto
写example.proto文件以及.go文件测试。由于proto生成go文件的命令是
protoc --go_out=./ example.proto
PS:
1.如果你是直接go get了gin、beego这种,一般就会顺便给你安装protobuf以及protoc-gen-go了。
2.如果你有protoc-gen-go代码,放到对应目录下后($GOPATH/src/github.com/golang/protobuf/),
make install也可以手动安装protoc-gen-go
二、使用protobuf
1.example.proto示例文件
(具体语法请自行搜索)syntax = "proto2"; //example.proto package example; // LD message LD { required uint32 ip = 1; // LD的IP } // 集群 message Set { required uint32 id = 1; // SET的id required string name = 2; // SET名字 repeated LD ld_list = 3; // LD列表 }
注意required是必须要求的字段,optional是可选字段,同时注意, id=1, 后面的数字主要是保证其顺序与唯一性。
编译命令
protoc --go_out=./ example.proto
会生成文件example.pb.go
生成的代码如下:
// Code generated by protoc-gen-go. DO NOT EDIT. // source: example.proto /* Package example is a generated protocol buffer package. It is generated from these files: example.proto It has these top-level messages: LD Set */ package example import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // LD type LD struct { Ip *uint32 `protobuf:"varint,1,req,name=ip" json:"ip,omitempty"` XXX_unrecognized []byte `json:"-"` } func (m *LD) Reset() { *m = LD{} } func (m *LD) String() string { return proto.CompactTextString(m) } func (*LD) ProtoMessage() {} func (*LD) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } func (m *LD) GetIp() uint32 { if m != nil && m.Ip != nil { return *m.Ip } return 0 } // 集群 type Set struct { Id *uint32 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` LdList []*LD `protobuf:"bytes,3,rep,name=ld_list,json=ldList" json:"ld_list,omitempty"` XXX_unrecognized []byte `json:"-"` } func (m *Set) Reset() { *m = Set{} } func (m *Set) String() string { return proto.CompactTextString(m) } func (*Set) ProtoMessage() {} func (*Set) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (m *Set) GetId() uint32 { if m != nil && m.Id != nil { return *m.Id } return 0 } func (m *Set) GetName() string { if m != nil && m.Name != nil { return *m.Name } return "" } func (m *Set) GetLdList() []*LD { if m != nil { return m.LdList } return nil } func init() { proto.RegisterType((*LD)(nil), "example.LD") proto.RegisterType((*Set)(nil), "example.Set") } func init() { proto.RegisterFile("example.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ // 126 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4d, 0xad, 0x48, 0xcc, 0x2d, 0xc8, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0x72, 0x95, 0x44, 0xb8, 0x98, 0x7c, 0x5c, 0x84, 0xf8, 0xb8, 0x98, 0x32, 0x0b, 0x24, 0x18, 0x15, 0x98, 0x34, 0x78, 0x83, 0x98, 0x32, 0x0b, 0x94, 0xfc, 0xb9, 0x98, 0x83, 0x53, 0x4b, 0xc0, 0xc2, 0x29, 0x70, 0xe1, 0x14, 0x21, 0x21, 0x2e, 0x96, 0xbc, 0xc4, 0xdc, 0x54, 0x09, 0x26, 0x05, 0x26, 0x0d, 0xce, 0x20, 0x30, 0x5b, 0x48, 0x85, 0x8b, 0x3d, 0x27, 0x25, 0x3e, 0x27, 0xb3, 0xb8, 0x44, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x88, 0x5b, 0x0f, 0x66, 0x95, 0x8f, 0x4b, 0x10, 0x5b, 0x4e, 0x8a, 0x4f, 0x66, 0x71, 0x09, 0x20, 0x00, 0x00, 0xff, 0xff, 0xce, 0x69, 0x42, 0x70, 0x7f, 0x00, 0x00, 0x00, }
特别注意: 生成的文件中的package是example, 那么文件必须放在example文件夹下! 否则会报错: “can’t load package: package example
下面写一个测试程序:
// main.go package main import ( "fmt" t "./example" "github.com/golang/protobuf/proto" ) func main(){ // 创建一个对象, 并填充字段, 可以使用proto中的类型函数来处理例如Int32(XXX) var hw t.Set var ld t.LD ld = t.LD { Ip: proto.Uint32(666), } hw = t.Set { Id: proto.Uint32(1), Name: proto.String("hello"), //LdList.append(ld), } // 对数据进行编码, 注意参数是message指针 mData, err := proto.Marshal(&hw) if err != nil { fmt.Println("Error1: ", err) return } // 下面进行解码, 注意参数 var umData t.Set err = proto.Unmarshal(mData, &umData) if err != nil { fmt.Println("Error2: ", err) return } // 输出结果 fmt.Println(*umData.Id, " ", *umData.Name, " ", *ld.Ip) }
目录结构
feiqianyousadeMacBook-Pro:protobuf yousa$ ls apigw_agent.proto common.proto example.pb.go main protobuf-cpp-3.4.1.tar.gz test.proto apigw_master.proto example example.proto main.go test.pb.go feiqianyousadeMacBook-Pro:protobuf yousa$ tree-d -bash: tree-d: command not found feiqianyousadeMacBook-Pro:protobuf yousa$ tree -d . └── example 1 directory feiqianyousadeMacBook-Pro:protobuf yousa$ ls ./example example.pb.go
编译&运行
go build main.go
./main
参考
go protobuf:https://github.com/golang/protobufproto文档:https://godoc.org/github.com/golang/protobuf/proto
相关文章推荐
- golang 安装使用 protobuf 的教程
- golang 使用 protobuf 的教程
- Golang里面使用protobuf(proto3)
- win protobuffer使用简易教程
- golang使用protobuf例子
- golang使用protobuf
- ProtoBufPaser工具使用教程
- protobuf使用和教程
- Golang里面使用protobuf(proto3)
- golang中protobuf使用
- Go实战--golang中使用gRPC和Protobuf实现高性能api(golang/protobuf、google.golang.org/grpc)
- mac 下配置 protobuf golang插件 并使用
- 基于protobuf service使用rpc入门教程
- Android逆向---Fiddler简易使用教程之使用(2)
- 在C语言环境下使用google protobuf
- iOS 基于Socket使用Protobuf进行数据传输
- OkHttp简易使用教程
- linux下安装protobuf教程+示例(详细)
- 最常用的两种C++序列化方案的使用心得(protobuf和boost serialization)
- 使用Protobuf的一些经验总结