介绍

flatbuffer是google发布的一个跨平台序列化框架具有如下特点

1、对序列化的数据不需要打包和拆包

2、内存和效率速度高,扩展灵活

3、代码依赖较少

4、强类型设计,编译期即可完成类型检查

5、使用简单、可跨平台使用

安装

git clone git@github.com:google/flatbuffers.git
cd flatbuffers
brew install cmake
cmake -G "Unix Makefiles"
make
make install
flatc --version

编写flatbuffer文件

// Example IDL file for our monster's schema.
namespace com.frank.learning;
enum Color:byte { Red = , Green, Blue = }
union Equipment { Weapon } // Optionally add more tables.
struct Vec3 {
x:float;
y:float;
z:float;
}
table Monster {
pos:Vec3; // Struct.
mana:short = ;
hp:short = ;
name:string;
friendly:bool = false (deprecated);
inventory:[ubyte]; // Vector of scalars.
color:Color = Blue; // Enum.
weapons:[Weapon]; // Vector of tables.
equipped:Equipment; // Union.
}
table Weapon {
name:string;
damage:short;
}
root_type Monster;

将文件保存为monster.fbs,下面进行编译

flatc --java monster.fbs

执行完后会在当前目录下生成Java文件

IntelliJ测试flatbuffer

将生成的Java代码拷到项目中,新建SampleBinary类

package com.frank.learning;

import com.google.flatbuffers.FlatBufferBuilder;

import java.nio.ByteBuffer;

public class SampleBinary {

    public static void  main(String[] args){

        //使用FlatBufferBuilder 完成对象序列化
FlatBufferBuilder builder = new FlatBufferBuilder(1024); //返回该String的偏移地址
int weaponOneName = builder.createString("Sword");
short weaponOneDamage = 3;
int weaponTwoName = builder.createString("Axe");
short weaponTwoDamage = 5; // 使用createWeapon创建Weapon对象,并返回该对象的偏移地址
int sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage);
int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage); // Serialize a name for our monster, called "Orc".
int name = builder.createString("Orc"); // 创建一个Vector对象,并且返回它的偏移地址
byte[] treasure = {0, 1, 13, 12, 4, 5, 6, 7, 8, 9};
int inv = Monster.createInventoryVector(builder, treasure); // Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
// create a FlatBuffer vector.
int[] weaps = new int[2];
weaps[0] = sword;
weaps[1] = axe;
// Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
int weapons = Monster.createWeaponsVector(builder, weaps); // startMonster声明开始创建Monster对象,使用endMonster声明完成Monster对象
Monster.startMonster(builder);
Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f));
Monster.addName(builder, name);
Monster.addColor(builder, Color.Red);
Monster.addHp(builder, (short)300);
Monster.addInventory(builder, inv);
Monster.addWeapons(builder, weapons);
Monster.addEquippedType(builder, Equipment.Weapon);
Monster.addEquipped(builder, axe);
int orc = Monster.endMonster(builder); // 调用finish方法完成Monster对象
builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`. // 生成二进制文件
byte[] buf = builder.sizedByteArray(); // 至此完成对象数据序列化 //模拟从获取到二进制数据 进行反序列化对象
ByteBuffer buffer = ByteBuffer.wrap(buf); //根据该二进制数据列生成Monster对象
Monster monster = Monster.getRootAsMonster(buffer); short hp = monster.hp();
System.out.println(hp); short mana = monster.mana();
System.out.println(mana);
String resultName = monster.name();
System.out.println(resultName); Vec3 pos = monster.pos();
float x = pos.x();
float y = pos.y();
float z = pos.z();
System.out.println("X: "+x+" Y: "+y+" Z: "+z); int invLength = monster.inventoryLength();
int thirdItem = monster.inventory(2);
System.out.println(thirdItem); int weaponsLength = monster.weaponsLength();
String secondWeaponName = monster.weapons(1).name();
short secondWeaponDamage = monster.weapons(1).damage();
System.out.println("weaponsLength: "+weaponsLength+" secondWeaponName: "+secondWeaponName+" secondWeaponDamage: "+secondWeaponDamage);
int unionType = monster.equippedType();
if (unionType == Equipment.Weapon) {
Weapon weapon = (Weapon)monster.equipped(new Weapon()); // Requires explicit cast
// to `Weapon`.
String weaponName = weapon.name(); // "Axe"
short weaponDamage = weapon.damage(); //
System.out.println("weaponName: "+weaponName+" weaponDamage: "+weaponDamage);
}
}
}

pom文件加入flatbuffer相关jar包

<dependency>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-java</artifactId>
<version>1.12.0</version>
</dependency>

输出结果如下

300
150
Orc
X: 1.0 Y: 2.0 Z: 3.0
13
weaponsLength: 2 secondWeaponName: Axe secondWeaponDamage: 5
weaponName: Axe weaponDamage: 5

flatbuffer原理

flatbuffer将数据存在一个一维数组当中,缓存在一个bytebuffer当中。一个flatbuffer对象在数组中被分为两部分,元数据部分和数据部分。元数据负责存放相对于中间部分的索引,数据部分存放真实的value。分割的节点为(pivot point)。它的将数据以及对应的数据位置都保存在一个线性的数组中。使用的时候只需要把byte流发送出去,解析的时候只需要根据保存的位置,截取对应的数值即可。

例子:
假设我们创建了一个Person对象,它的name是John,friendshipStatus是2.那么对应图中元数据部分第一个byte是1--->从中心点处数一个位置,开始的字符就是name的值即john。第二个byte是6,从中心点数6个位置值是2.
class Person {
String name;//john
int friendshipStatus;//
Person spouse;
List<Person>friends;
}

从图中可以看出来,flatbuffer将索引和数据文件存在一个一位数组中通过查找,还原对象,所以不需要打包和拆包的过程相对高效。

参考学习链接

1、https://www.jianshu.com/p/8df23cd182ec

2、https://www.jianshu.com/p/fa999434776a

3、https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html

flatbuffer介绍和用法的更多相关文章

  1. oc-12-NSString 类简单介绍及用法

    // 11-[掌握]NSString 类简单介绍及用法 #import <Foundation/Foundation.h> int main(int argc, const char * ...

  2. WorkFlow介绍及用法

    WorkFlow介绍及用法 说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配 ...

  3. Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法

    Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...

  4. vue第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法)

    第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法) #课程目标 了解 vue 框架的特点 掌握创建 vue 实例 掌握 data ...

  5. ServletContext介绍和用法总结

    ServletContext介绍和用法总结 学习总结 一.ServletContext 介绍 1. 概念 2. 作用 3. 获取 3.1 在实现类中获取 3.2 在 Spring 容器中获取 二.Se ...

  6. 08_android入门_android-async-http开源项目介绍及用法

    android-async-http开源项目可以是我们轻松的获取网络数据或者向server发送数据.使用起来很easy,关于android-async-http开源项目的介绍内容来自于官方:http: ...

  7. JMS学习篇《一》ActiveMQ消息中间件的简单介绍与用法-概念篇

    原创说明:本篇博文为本人原创作品,转载请注明出处 1.何为消息中间件 消息中间件是一种在分布式应用中互相交换信息的一种技术,常见的成熟消息中间件有:RabbitMQ.SonicMQ,activeMQ. ...

  8. Cookie、Session登陆验证相关介绍和用法

    一.Cookie和Session 首先.HTTP协议是无状态的:所谓的无状态是指每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应直接影响,也不会直接 ...

  9. 内置锁(一)synchronized 介绍与用法

    一.synchronized 的介绍   synchronized 是 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码,而这段代码也被称 ...

随机推荐

  1. 关于SpringBoot集成myBatis时,mapper接口注入失败的问题

    问题描述: 在Spring Boot集成myBatis时,发现启动时,mapper接口一直注入失败. 现象如下: VehicleDAO就是需要的mapper对象,一个简单的接口. 已经在applica ...

  2. 老男孩Linux运维50期 --于海科--决心书

    1.我叫于海科,来自于甘肃省天水市,之前就读于兰州石化职业技术学院,我是听之前的学长说老男孩教育出来就业不错,我特此来这培训希望出来能够找到一份不错的工作.2.五个月学完,目标薪资是11k.3.达到目 ...

  3. ROC-RK3328-CC开源主板运行LibreELEC系统

    LibreELEC是运行Kodi媒体中心的轻量级操作系统,基于Linux内核发行,系统为适配Kodi运行环境,做了许多优化和精简,运行速度快,操作简单.是一款很优秀的多功能播放器操作系统. ROC-R ...

  4. 【阅读笔记】Ranking Relevance in Yahoo Search (四 / 完结篇)—— recency-sensitive ranking

    7. RECENCY-SENSITIVE RANKING 作用: 为recency-sensitive的query提高排序质量: 对于这类query,用户不仅要相关的还需要最新的信息: 方法:rece ...

  5. Codeforces Round #622 (Div. 2) 1313 C1

    C1. Skyscrapers (easy version) time limit per test1 second memory limit per test512 megabytes inputs ...

  6. UVA352 The Seasonal War

    本文为UserUnknown原创 题目本身不难理解,就是深搜(或广搜,有可能以后会加在这里). 但是洛谷的题目中没有截到输入输出的格式,下面是我从UVA复制下来的样例: Sample input 6 ...

  7. IIS搭建网站(二)

    win+IIS+ASP+ACCESS第二种搭建方式 安装 控制面板”,依次选“添加/删除程序”, 添加/删除Windows组件 在应用程序服务器前打钩.点击详细信息 将“Internet信息服务(II ...

  8. javascript阻止子元素继承父元素事件

    $('.box').on('click', function (e) { if(e.target == this) { console.log(e.target) } })

  9. 整理高度塌陷与BFC

    当面试官问道你高度塌陷时,人们第一想到的方法一定是 .clearfix::after { content: ''; display: block; clear: both; visibility: h ...

  10. springboot关于webmvc配置问题记录

    在之前的文章(springboot配置静态资源访问路径)中说过,springboot默认的加载静态资源的地方是在resources目录下的static文件夹下,其实除了resources目录下得sta ...