夸智网
扫描关注夸智网

手机扫描二维码

Golang中将字节流转为Protobuf

夸智网2023-09-19博客 11 0A+A-

  在接入第三方数据流或接入物联网设备时,通常这些数据所上报的数据只是按照指定的协议所编码,上报的数据流也不够紧凑,如我们直接存储这类字节流数据也比较大。此时可以将字节流转为其他压缩格式的流,如Protobuf等;

  将字节流转为Protobuf流具体流程为:定义Proto文件、生成对应的Proto对象、读取流数据写入Proto对象、序列化Proto对象。

定义Proto文件:

syntax = "proto3";

//包名,通过protoc生成时go文件

package data;

//位置

message position {

int32 type = 1;

int32 lon = 2;

int32 lat= 3;

string status = 4;

}

程序

  将字节数据转为Protobuf所生成的对象;

数据流协议为7E头7E尾,简单起见这里就不使用转码了,字节格式如下。

   7E-类型-经度-纬度-状态长度-状态

str := "7E0106C1FC5A0160C9640231327E"

buf := bytes.NewBuffer(toBytes(str))

p :=&test.Position{}

//跳过头

buf.Next(1)

//读取类型

var b byte

b,_=buf.ReadByte()

p.Type = int32(b)

//获取经度

lon:=[]byte{0,0,0,0}

buf.Read(lon)

p.Lon=bytesToInt(lon)

//获取纬度

lat:=[]byte{0,0,0,0}

buf.Read(lat)

p.Lat=bytesToInt(lat)

//获取状态

len,_:=buf.ReadByte()

//获取len个长度的字节数组

data:= buf.Next(int(len))

p.Status=string(data)

fmt.Println("对象输出:",p.String())

fmt.Println("Protobuf序列化: ",hex.EncodeToString(pData))

fmt.Println("原始数据:",str)

输出结果:

  对象输出: type:1 lon:113376346 lat:23120228 status:"12"

  Protobuf序列化: 080110daf8873618e492830b22023132

  原始数据: 7E0106C1FC5A0160C9640231327E

  由于这个例子数据字段比较少,并没有看出Protobuf序列化的优势,具体对比可看这篇文章:透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化

查看原文

发表评论