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

待学习,后补充

用法概述

  1. 自定义schema文件,定义序列化数据的数据结构(其中包括root对象,具体在schema章节展开);
  2. 通过FlatBuffers编译器flatc根据编译选项将schema文件生成相应开发语言的依赖文件,如C++的--cpp,生成.h头文件;
  3. 使用FlatBufferBuilder类去构造一个二进制buffer,然后引用上一步生成的头文件中的API在buffer中序列化数据对象并存储;
  4. 数据传输;
  5. 接收方通过调用相应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初识相关推荐

  1. day3----编码-集合-深浅copy-文件操作-函数初识

    day3----编码-集合-深浅copy-文件操作-函数初识 本文档主要内容: 一 编码 二 集合 三 深浅copy 四 文件操作 五 函数初识 首先,我们来看看两个字符串的比较 打开cmd,进入do ...

  2. ⑥python模块初识、pyc和PyCodeObject

    一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...

  3. 初识java类的接口实现

    初识java类的接口实现 如果两个类之间不存在继承关系,且两个类都想实现同一个接口,两个类都必须实现接口中全部方法,否则报语法错误 如果两个类之间存在继承关系也想实现同一个接口,父类如果实现了某个接口 ...

  4. vba 编辑combobox内容_初识Visual Basic编辑器并建立一段简单的代码

    大家好,从今日开始我正式推出"VBA之EXCEL应用"教程,这个教程是面向初学人员的教程,教程一共三册,十七个章节,从简单的录制宏实现一直讲到窗体的搭建,都是我们在利用EXCEL工 ...

  5. 16.1、python初识面向对象(1)

    初识面向对象 楔子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人 ...

  6. 精通Python网络爬虫:核心技术、框架与项目实战.1.1 初识网络爬虫

    摘要 网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理.在大数据时代,信息的采集是一项重要的工作,如果单纯靠人力进行信息采集,不仅低效繁琐,搜集的成本也会提高.此时,我们 ...

  7. 初识mysql数据字段属性_MySQL数据库~~~~初识、基础数据类型

    一 数据库初识 1.1 什么是数据库 数据库(DataBase,简称DB),简而言之可视为电子化的文件柜----存储电子文件的处所,用户可以对文件中的数据运行新增,截取,更新,删除等操作. 所谓数据库 ...

  8. Nancy in .Net Core学习笔记 - 初识Nancy

    原文:Nancy in .Net Core学习笔记 - 初识Nancy 前言 去年11月份参加了青岛MVP线下活动,会上老MVP衣明志介绍了Nancy, 一直没有系统的学习一下,最近正好有空,就结合. ...

  9. Python 函数初识 (1)

    一.今日主要内容 认识函数 函数:对功能或者动作的封装(定义) 语法: def 函数名字(形参) 函数体 函数的调用格式:函数名(实参) 函数的返回值 关键字:return 终止函数的运行 1.函数内 ...

最新文章

  1. 深度讲解:web前端性能优化
  2. MDaemon无法发送加密附件
  3. python之路_前端基础之jQuery入门2
  4. 使用Python和Numpy进行波士顿房价预测任务(二)【深度学习入门_学习笔记】
  5. plt.Circle()
  6. 746. Min Cost Climbing Stairs
  7. [OGRE]最小ogre程序的流程
  8. ae效果英文版翻译对照表_AE CS6 最全特效中英翻译
  9. ubuntu中的 magick++编程问题及编译方法
  10. 微信客服介绍和使用指引(4.19)
  11. 南邮 | 计算机图形学大作业:Skybox + Shadow volume
  12. unity 粒子系统面板参数释义
  13. DHCP 解决单位网络私接路由器的办法
  14. 建筑师妹岛和世为日本西武设计新型旗舰“球形车头”列车
  15. mysql 嵌套查询性能_MySQL数据库之嵌套查询与连接查询的性能详解
  16. Axure 制作验证码交互
  17. 进阶题73 纯粹合数
  18. Python安装包报错ERROR: Could not find a version that satisfies the requirement XXX解决方法
  19. 腾讯安全发布《银行业数据安全白皮书》 指明建设数据安全体系四大要素
  20. 研究生就业率排行前10!每一所都值得pick!

热门文章

  1. [架构之路-25]:目标系统 - 系统软件 - bootloader uboot内存映射与启动流程
  2. [Hearthstone]梦想战
  3. Mac备忘录内容突然全部消失恢复
  4. 微信小程序开发、uni-app开发、腾讯AI、百度AI
  5. 快手高层动荡:CTO陈定佳离职 两位高级副总裁将分担其职责
  6. 基于C语言实现的关键字检索系统
  7. 研究生导师的选择有哪些建议分享?
  8. matlab 编程之代码规范
  9. UEFI开发探索28 – 用Windbg建立UEFI调试环境
  10. LOVER婚恋软件技术支持网站声明