flatbuffer介绍和用法
介绍
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介绍和用法的更多相关文章
- oc-12-NSString 类简单介绍及用法
// 11-[掌握]NSString 类简单介绍及用法 #import <Foundation/Foundation.h> int main(int argc, const char * ...
- WorkFlow介绍及用法
WorkFlow介绍及用法 说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配 ...
- Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法
Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...
- vue第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法)
第四单元(初识vue-在页面中直接引入vue框架-学习使用vue语法-vue的指令-介绍data用法-methods用法) #课程目标 了解 vue 框架的特点 掌握创建 vue 实例 掌握 data ...
- ServletContext介绍和用法总结
ServletContext介绍和用法总结 学习总结 一.ServletContext 介绍 1. 概念 2. 作用 3. 获取 3.1 在实现类中获取 3.2 在 Spring 容器中获取 二.Se ...
- 08_android入门_android-async-http开源项目介绍及用法
android-async-http开源项目可以是我们轻松的获取网络数据或者向server发送数据.使用起来很easy,关于android-async-http开源项目的介绍内容来自于官方:http: ...
- JMS学习篇《一》ActiveMQ消息中间件的简单介绍与用法-概念篇
原创说明:本篇博文为本人原创作品,转载请注明出处 1.何为消息中间件 消息中间件是一种在分布式应用中互相交换信息的一种技术,常见的成熟消息中间件有:RabbitMQ.SonicMQ,activeMQ. ...
- Cookie、Session登陆验证相关介绍和用法
一.Cookie和Session 首先.HTTP协议是无状态的:所谓的无状态是指每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应直接影响,也不会直接 ...
- 内置锁(一)synchronized 介绍与用法
一.synchronized 的介绍 synchronized 是 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码,而这段代码也被称 ...
随机推荐
- nginx开启ssl并把http重定向到https的两种方式
1 简介 Nginx是一个非常强大和流行的高性能Web服务器.本文讲解Nginx如何整合https并将http重定向到https. https相关文章如下: (1)Springboot整合https原 ...
- varnish4.0缓存代理配置
防伪码:你必须非常努力,才能看起来毫不费力. 一.varnish原理: 1)Varnish简介: varnish缓存是web应用加速器,同时也作为http反向缓存代理.你可以安装varnish在任何h ...
- JS基础入门篇(十)— 数组方法
1.join 作用: 将数组通过指定字符拼接成字符串.语法: string arr.join([separator = ',']);参数: separator可选,如果省略的话,默认为一个逗号.如果 ...
- ip地址与运算 ipcalc命令
http://man.linuxde.net/ipcalc 转载于:https://blog.51cto.com/sonlich/2064133
- 2) 接口规范 原生django接口、单查群查 postman工具 CBV源码解析
内容了解 """ .接口:什么是接口.restful接口规范 .CBV生命周期源码 - 基于restful规范下的CBV接口 .请求组件.解析组件.响应组件 .序列化组件 ...
- http抓包—Content-Type讲解
1.Content-Type的定义 Content-Type(MediaType),即是Internet Media Type,互联网媒体类型,也叫做MIME类型.在互联网中有成百上千中不同的数据类型 ...
- jacoco 生成单测覆盖率报告
一.jacoco 简介 jacoco 是一个开源的覆盖率工具,它针对的开发语言是 java.其使用方法很灵活,可以嵌入到 ant.maven 中:可以作为 Eclipse 插件:可以作为 javaAg ...
- JUC之CAS
CAS(全称为CompareAndSwap,也有说是CompareAndSet,都差不多)是一条CPU并发原语,它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,判断预期值和更改新值的 ...
- NDK clang编译器的一个bug
NDK clang编译器的一个bug 问题代码 float32_t Sum_float(float32_t *data, const int count) { float32x4_t res = vd ...
- Linux内核驱动学习(五)KThread学习总结
文章目录 简介 例程 运行结果 参考 简介 使用内核线程需要包含头文件#include <linux/kthread.h>,下面整理了一下常用的api接口,如下表格所示: 函数 功能 st ...