FlatBuffers初识
FlatBuffers初识
文章目录
- FlatBuffers初识
- 概述
- 为什么使用FlatBuffers
- 对标ProcotolBuffers、JSON
- 用法概述
- 编译构建
- 定义数据结构
- schema示例文件:
- IDL 语法
- 数据类型概述
- 编译schema文件
- 序列化与访问
- 示例文件:
- Object based API (C++)
- mutable 变量
- 实现原理
- 性能比较
概述
FlatBuffers一开始是由Google开发用来支持性能高要求的游戏应用的一个开源的序列化工具库,由于其高效性、跨平台,同时支持多语言开发,而后经常被应用在各种传输性能高要求的互联网、物联网等应用场景。
本文仅为个人理解所作,详细请参考官方文档https://google.github.io/flatbuffers/index.html
为什么使用FlatBuffers
- 无需解析即可访问经序列化的数据:FlatBuffers是通过在一个扁平的buffer(一维数组)中存储二进制数据,数据无需经解析即可访问;
- 内存使用高效:访问序列化数据仅需序列化数据时所申请的buffer,经常性与共享内存IPC一起使用实现高效的性能需求;
- 灵活性:序列化数据"table“结构向前与向后同时兼容;
- 强类型:错误发生在编译期,无需在运行期通过代码断言;
- 引用方便:只需要添加一组头文件和一个自定义的生成头文件即可
- 跨平台
对标ProcotolBuffers、JSON
待学习,后补充
用法概述
- 自定义schema文件,定义序列化数据的数据结构(其中包括root对象,具体在schema章节展开);
- 通过FlatBuffers编译器
flatc
根据编译选项将schema文件生成相应开发语言的依赖文件,如C++的--cpp
,生成.h
头文件; - 使用
FlatBufferBuilder
类去构造一个二进制buffer,然后引用上一步生成的头文件中的API在buffer中序列化数据对象并存储; - 数据传输;
- 接收方通过调用相应API在buffer中获取到root对象的指针,通过类似于
object->field()
的方式直接访问数据;
编译构建
FlatBuffers官方提供了多种编译构建的方法,此处仅介绍基于Linux平台的CMake编译构建,其余请参考官方文档:
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
make
编译完成,工程根目录下生成flatc
可执行文件,即FlatBuffers编译器
定义数据结构
FlatBuffers在scheme文件使用IDL语言(Interface Definition Languange)自定义数据结构,从本节起我将由一个具体的FlatBuffers使用示例展开用法介绍:
schema示例文件:
//jocker.fbs
namespace StudySample;table Weapon
{name : string;hurt : short;
}
table Corselet
{name : string;damage : short =100;
}
union Equiment
{weapon : Weapon,corselet : Corselet
}
struct Vec3
{x : float;y : float;z : float;
}table Jocker
{name : string;hp : short =100;friends : bool =true;equiment : Equiment;weapons : [Weapon];pos : Vec3;path : [Vec3];scope : [short];
}
root_type Jocker;
IDL 语法
- 定义: 变量 :类型 默认值 (可选字段);
- 由
root_type
指定序列化的根数据对象
数据类型概述
- 整型
- 字符串:string
- 布尔型
- 结构体
- 联合体
- 数组:由方括号
[]
定义数据类型,固定的内存存储消耗,相比于table内存占用低访问快 - table:FlatBuffers所提供的同时向前向后兼容的数据结构,可末尾字段增加字段,亦可通过关键字
deprecated
禁用字段
编译schema文件
以c++为例:./${FLATBUFFERS_DIR}/flatc --cpp ${EXAMPLE_DIR}/jocker.fbs
${FLATBUFFERS_DIR}
:FlatBuffers工程目录${EXAMPLE_DIR}
:示例工程目录
编译成功后会在当前目录下生成FlatBuffers序列化数据所依赖的.h
头文件
序列化与访问
示例文件:
#include "jocker.h"
using namespace StudySample;uint8_t* BuildFlatbuffers(void)
{flatbuffers::FlatBufferBuilder builder(1024);auto sword_name = builder.CreateString("sword");auto sword = CreateWeapon(builder, sword_name, 20);auto axe_name = builder.CreateString("axe");auto axe = CreateWeapon(builder, axe_name, 30);auto cuff_name = builder.CreateString("icon-cuff");auto cuff = CreateCorselet(builder, cuff_name, 30);Vec3 position = {3.0f, 4.0f, 5.0f};//Jocker buffer buildauto name = builder.CreateString("Yiff");std::vector<flatbuffers::Offset<Weapon>> offset_weapons;offset_weapons.push_back(sword);offset_weapons.push_back(axe);auto weapons = builder.CreateVector(offset_weapons);std::vector<Vec3> vec_Vec3 = {Vec3(1.0f, 0.0f, 0.0f), Vec3(1.0f, 2.0f, 0.0f), Vec3(1.0f, 2.0f, 3.0f)};auto path = builder.CreateVectorOfStructs(vec_Vec3);short scope_array[] = {69, 75, 77};auto scope = builder.CreateVector(scope_array, 3); //Method1// auto jocker = CreateJocker(builder, name, 100, true, Equiment_weapon, sword.Union(), weapons, &position, path, scope);// builder.Finish(jocker);//Method2JockerBuilder jocker_builder(builder);jocker_builder.add_name(name);jocker_builder.add_hp(100);jocker_builder.add_friends(true);jocker_builder.add_equiment_type(Equiment_weapon);jocker_builder.add_equiment(sword.Union());jocker_builder.add_weapons(weapons);jocker_builder.add_pos(&position);jocker_builder.add_path(path);jocker_builder.add_scope(scope);auto jocker = jocker_builder.Finish();builder.Finish(jocker);return builder.GetBufferPointer();
}void ParseFlatbuffers(uint8_t* pbuff)
{auto jocker = GetJocker(pbuff);std::cout << "Jocker name: " << jocker->name()->str() << std::endl;std::cout << "Jocker hp: " << jocker->hp() << std::endl;std::cout << "Jocker attr(1-friend, 0-enemy): " << jocker->friends() << std::endl;std::cout << "Jocker equnimet: " << (static_cast<const Weapon*>(jocker->equiment()))->name()->str() << " and its data: " << (static_cast<const Weapon*>(jocker->equiment()))->hurt() << std::endl;std::cout << "Jocker position: " << jocker->pos()->x() << "-" << jocker->pos()->y() << "-" << jocker->pos()->z() << std::endl;std::cout << "Jocker path position2-y:" << jocker->path()->Get(1)->y() << std::endl;std::cout << "Jocker scope2:" << jocker->scope()->Get(1) << std::endl;
}
上述展示了两种构建buffer的API:Method1与Method2
Object based API (C++)
由FlatBuffers官方针对C++编程语言特点而编写的一套API
- 编译选项
--gen-object-api
- 效率性能不如原生用法,但是序列化与反序列化适用C++ STL,构建buffer方便
mutable 变量
应用需要进行学习后再补充
实现原理
待了解补充
性能比较
待了解补充
FlatBuffers初识相关推荐
- day3----编码-集合-深浅copy-文件操作-函数初识
day3----编码-集合-深浅copy-文件操作-函数初识 本文档主要内容: 一 编码 二 集合 三 深浅copy 四 文件操作 五 函数初识 首先,我们来看看两个字符串的比较 打开cmd,进入do ...
- ⑥python模块初识、pyc和PyCodeObject
一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...
- 初识java类的接口实现
初识java类的接口实现 如果两个类之间不存在继承关系,且两个类都想实现同一个接口,两个类都必须实现接口中全部方法,否则报语法错误 如果两个类之间存在继承关系也想实现同一个接口,父类如果实现了某个接口 ...
- vba 编辑combobox内容_初识Visual Basic编辑器并建立一段简单的代码
大家好,从今日开始我正式推出"VBA之EXCEL应用"教程,这个教程是面向初学人员的教程,教程一共三册,十七个章节,从简单的录制宏实现一直讲到窗体的搭建,都是我们在利用EXCEL工 ...
- 16.1、python初识面向对象(1)
初识面向对象 楔子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人 ...
- 精通Python网络爬虫:核心技术、框架与项目实战.1.1 初识网络爬虫
摘要 网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理.在大数据时代,信息的采集是一项重要的工作,如果单纯靠人力进行信息采集,不仅低效繁琐,搜集的成本也会提高.此时,我们 ...
- 初识mysql数据字段属性_MySQL数据库~~~~初识、基础数据类型
一 数据库初识 1.1 什么是数据库 数据库(DataBase,简称DB),简而言之可视为电子化的文件柜----存储电子文件的处所,用户可以对文件中的数据运行新增,截取,更新,删除等操作. 所谓数据库 ...
- Nancy in .Net Core学习笔记 - 初识Nancy
原文:Nancy in .Net Core学习笔记 - 初识Nancy 前言 去年11月份参加了青岛MVP线下活动,会上老MVP衣明志介绍了Nancy, 一直没有系统的学习一下,最近正好有空,就结合. ...
- Python 函数初识 (1)
一.今日主要内容 认识函数 函数:对功能或者动作的封装(定义) 语法: def 函数名字(形参) 函数体 函数的调用格式:函数名(实参) 函数的返回值 关键字:return 终止函数的运行 1.函数内 ...
最新文章
- 深度讲解:web前端性能优化
- MDaemon无法发送加密附件
- python之路_前端基础之jQuery入门2
- 使用Python和Numpy进行波士顿房价预测任务(二)【深度学习入门_学习笔记】
- plt.Circle()
- 746. Min Cost Climbing Stairs
- [OGRE]最小ogre程序的流程
- ae效果英文版翻译对照表_AE CS6 最全特效中英翻译
- ubuntu中的 magick++编程问题及编译方法
- 微信客服介绍和使用指引(4.19)
- 南邮 | 计算机图形学大作业:Skybox + Shadow volume
- unity 粒子系统面板参数释义
- DHCP 解决单位网络私接路由器的办法
- 建筑师妹岛和世为日本西武设计新型旗舰“球形车头”列车
- mysql 嵌套查询性能_MySQL数据库之嵌套查询与连接查询的性能详解
- Axure 制作验证码交互
- 进阶题73 纯粹合数
- Python安装包报错ERROR: Could not find a version that satisfies the requirement XXX解决方法
- 腾讯安全发布《银行业数据安全白皮书》 指明建设数据安全体系四大要素
- 研究生就业率排行前10!每一所都值得pick!