介绍

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. java 之 构造器 static关键字

    构造器  特点: 方法名和类名一至,没有void没有返回,无参数的称为无参构造器,有参数的称为有参构造器 语法: public 类名 {数据类型 参数名} 目的:创建对象 注意:如果类中没有带有参数的 ...

  2. Intellij IDEA 使用Spring-boot-devTools

    转载地址:https://blog.csdn.net/u013938484/article/details/77541050 转载于:https://blog.51cto.com/881206524/ ...

  3. Swift-Realm数据库的使用详解

    Swift-Realm数据库的使用详解 概述 Realm 是一个跨平台的移动数据库引擎,其性能要优于 Core Data 和 FMDB - 移动端数据库性能比较, 我们可以在 Android 端 re ...

  4. bind()函数的深入理解及两种兼容方法分析

    在JavaScript中,bind()函数仅在IE9+.Firefox4+.Chrome.Safari5.1+可得到原生支持.本文将深入探讨bind()函数并对两种兼容方法进行分析比较.由于本文将反复 ...

  5. unittest(执行用例)

    from selenium import webdriver from time import sleep import unittest#导入unittest库 import HTMLTestRun ...

  6. Coursera课程笔记----计算导论与C语言基础----Week 2

    计算机的历史与未来(Week 2) 计算机历史 早期计算机:手工计算器➡️机械计算器➡️计算机原型 现代计算机:电子管计算机➡️晶体管计算机➡️集成电路计算机➡️超大规模集成电路 早期的手工计算辅助工 ...

  7. 【Kafka】Kafka简单介绍

    目录 基本介绍 概述 优点 主要应用场景 Kafka的架构 四大核心API 架构内部细节 基本介绍 概述 Kafka官网网站:http://kafka.apache.org/ Kafka是由Apach ...

  8. JAVA知识总结(四):单例模式和多态

    好吧,今天一定要把面向对象的最后一个特性:多态,给说完.不过我们先来聊一聊设计模式,因为它很重要. 设计模式 官方的解释是,设计模式是:一套被反复使用,多数人知晓的,经过分类编目,代码设计经验的总结. ...

  9. Linux内核驱动学习(九)GPIO外部输入的处理

    文章目录 前言 设备树 两个结构体 gpio_platform_data gpio_demo_device 两种方式 轮询 外部中断 总结 附录 前言 前面是如何操作GPIO进行输出,这里我重新实现了 ...

  10. u-boot 源码分析(1) 启动过程分析

    u-boot 源码分析(1) 启动过程分析 文章目录 u-boot 源码分析(1) 启动过程分析 前言 配置 源码结构 api arch board common cmd drivers fs Kbu ...