安裝使用
參考連結:blog.51cto.com/onebig/2122019
一、FlatBuffers簡介
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;
參考連結:github.com/halfrost/Halfrost-Field...
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 則是表現出各方面都很均衡的能力。
本作品採用《CC 協議》,轉載必須註明作者和本文連結