侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

go语言中Flatbuffer的安装及简单使用流程

Go  /  管理员 发布于 3年前   2211

FlatBuffers 为 Google 发布的一个跨平台,提供多种语言接口,注重性能和资源使用的序列化类库。

目前该类库提供 C++, C#, C, Go, Java, JavaScript, PHP, and Python 语言接口。

该序列化类库多用于移动端手游数据传输以及特定的对性能有较高要求的应用。 

接下来我们将学习 FlatBuffers 环境搭建并且使用 Java 语言完成一次简单的序列化例子。


编译 flatc 工具

编写一个 FlatBuffers 的 scheme 文件,.fbs 文件

使用 flatc 工具编译 scheme 文件,生成对应语言的数据对象头文件/类

使用 FlatBufferBuilder 序列化对象

反序列化数据对象


编译 flatc 工具

下载 flatc 源码

git clone git@github.com:google/flatbuffers.git
cd flatbuffers/
sudo cmake -G "Unix Makefiles" //生成makefile文件
sudo make 
sudo make install
flatc --version  //显示版本


编写 FlatBuffers 的 scheme 文件

基本类型:

8 bit: byte ubyte bool
16 bit: short ushort
32 bit: int uint float
64 bit: long ulong double

复杂类型:

数组 (用中括号表示 [type]). 不支持嵌套数组,可以用 table 实现
字符串 string, 支持 UTF-8 或者 7-bit ASCII. 对于其他编码可以用数组 [byte] 或者 [ubyte] 表示。
Struct 只支持基本类型或者嵌套 Struct
Table 类似 Struct,但是可以支持任何类型


test.fbs 编写

namespace Block;
table Block {
 id: long;
 hash: string;
 flag: bool;
 txs: [Tx];
}
table Tx {
 hash: string;
 value: double;
}
root_type Block;

Go 使用 FlatBuffers

编译 scheme 文件为 go 文件,会生成 Block.go, Tx.go 文件

flatc -g myschema.fbs

安装 go 扩展包

go get -v github.com/google/flatbuffers/go


序列化数据

把对象转为二进制数据:

package main
import (
  "fmt"
  fbs "letcode/flatbuff/fbs/block"
  flatbuffers "github.com/google/flatbuffers/go"
)
type Block struct {
  Id   int64
  Hash string
  Flag bool
  Txs  []Tx
}
type Tx struct {
  Hash  string
  Value float64
}
func main() {
  txone := Tx{Hash: "adfadf", Value: 123}
  txtwo := Tx{Hash: "adfadf", Value: 456}
  block := Block{Id: 1,Hash: "aadd",Flag: true,}
  //初始化buffer,大小为0,会自动扩容
  builder := flatbuffers.NewBuilder(0)
  //第一个交易
  txoneh := builder.CreateString(txone.Hash)//先处理非标量string,得到偏移量
  fbs.TxStart(builder)
  fbs.TxAddHash(builder, txoneh)
  fbs.TxAddValue(builder, txone.Value)
  ntxone := fbs.TxEnd(builder)
  //第二个交易
  txtwoh := builder.CreateString(txtwo.Hash)
  fbs.TxStart(builder)
  fbs.TxAddHash(builder, txtwoh)
  fbs.TxAddValue(builder, txtwo.Value)
  ntxtwo := fbs.TxEnd(builder)
  //block
  //先处理数组,string等非标量
  fbs.BlockStartTxsVector(builder, 2)
  builder.PrependUOffsetT(ntxtwo)
  builder.PrependUOffsetT(ntxone)
  txs := builder.EndVector(2)
  bh := builder.CreateString(block.Hash)
  //再处理标量
  fbs.BlockStart(builder)
  fbs.BlockAddId(builder, block.Id)
  fbs.BlockAddHash(builder, bh)
  fbs.BlockAddFlag(builder, block.Flag)
  fbs.BlockAddTxs(builder, txs)
  nb := fbs.BlockEnd(builder)
  builder.Finish(nb)
  buf := builder.FinishedBytes() //返回[]byte
  fmt.Println(buf)
}

要序列化 block,首先处理非标量的序列化,得到偏移量。


反序列化

读取二进制数据转为对象:

func DecodeToBlock(filename string) Block {
    var (
        block Block
    )
    buf, err := ioutil.ReadFile(filename)
    if err != nil {
        panic(err)
    }
    //传入二进制数据
    b := fbs.GetRootAsBlock(buf, 0)
    block.Flag = b.Flag()
    block.Hash = string(b.Hash())
    block.Id = b.Id()
    len := b.TxsLength()
    for i := 0; i < len; i++ {
        tx := new(fbs.Tx)
        ntx := new(Tx)
        if b.Txs(tx, i) {
            ntx.Hash = string(tx.Hash())
            ntx.Value = tx.Value()
        }
        block.Txs = append(block.Txs, *ntx)
    }
    return block
}


扩展知识:

编码性能:

flatbuf 的编码性能要比 protobuf 低。在 JSON、protobuf 和 flatbuf 之中,flatbuf 编码性能最差,JSON 介于二者之间。


编码后的数据长度:

由于通常情况下,传输的数据都会做压缩。在不压缩的情况下,flatbuffer 的数据长度是最长的,理由也很简单,因为二进制流内部填充了很多字节对齐的 0,并且原始数据也没有采取特殊的压缩处理,整个数据膨胀的更大了。不管压不压缩,flatbuffer 的数据长度都是最长的。JSON 经过压缩以后,数据长度会近似于 protocol buffer。protocol buffer 由于自身编码就有压缩,再经过 GZIP 这些压缩算法压缩以后,长度始终维持最小。


解码性能:

flatbuffer 是一种无需解码的二进制格式,因而解码性能要高许多,大概要比 protobuf 快几百倍的样子,因而比 JSON 快的就更多了。


总结

如果需要重度依赖反序列化的场景,可以考虑用 flatbuffer。

protobuf 则是表现出各方面都很均衡的能力。


  • 上一条:
    Laravel项目中使用kafka_laravel-kafka扩展包推荐
    下一条:
    PHP框架Kohana v3.3.6版本及Kohana_3_中文手册译本电子书下载链接分享
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-09
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-12
    • 2021-01
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-08
    • 2024-11
    • 2025-02
    • 2025-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客