网络传输优化----flatBuffer

1.优点

网络传输优化----flatBuffer_第1张图片
优点

2.使用方法

网络传输优化----flatBuffer_第2张图片
使用方法
  • 下载文件编译工具
    1.下载源码
    $ git clone https://github.com/google/flatbuffers
    2.下载编译工具
    https://cmake.org/download/ 下载对应的cmake工具

    参考网上:可以使用 cmake编译成flatc工具。但是暂时没有搞懂怎么编译?

    最后,在这个地方可以下载windows的 exe可以运用文件。
    https://github.com/google/flatbuffers/releases
    比较坑的最新的1.7.1没有exe没有exe下载。也没有看后面的,以为需要自己编译。最后一不留 神看到1.7.0有下载。哎。。。。。。。。

  • 编写描述
    使用 FlatBuffers 的 IDL 定义好数据结构 Schema,编写 Schema 的详细文档在这里 http://google.github.io/flatbuffers/flatbuffers_guide_writing_schema.html。
    参考一个例子

//包名
namespace com.xx.xx;
table Items {
    ItemId : long;
    timestemp : int;
    basic:[Basic];
}
 
table Basic{
  id:int;
  name:string;
  email:int;
  code:long;
  isVip:bool;
  count:int;
  carList:[Car];
}
 
table Car{
  id:long;
  number:long;
  describle:string;
}
 
root_type Items;
  • 使用工具

1.
网络传输优化----flatBuffer_第3张图片
工具使用

2.根据json生成和fbs 生成flatbuffer 二进制文件.bin
例如repos_json.json (有数据),对应的数据结构repos_schema.fbs ,生成repos_json.bin(二进制flatbuffer格式的)
$ ./flatc -j -b repos_schema.fbs repos_json.json

  • 工程中使用
    编写对应描述文件,翻译成对应语言的类。把对应的类, 放到你的工程中。
网络传输优化----flatBuffer_第4张图片
工程
  • 序列化于反序列化
public void serialize(View v){
    //==================序列化========================
    FlatBufferBuilder builder = new FlatBufferBuilder();
    int id1 = builder.createString("兰博基尼");
    //准备Car对象
    int car1 = Car.createCar(builder,10001L,88888L,id1);
    int id2 = builder.createString("奥迪A8");
    //准备Car对象
    int car2 = Car.createCar(builder,10001L,88888L,id2);
    int id3 = builder.createString("奥迪A9");
    //准备Car对象
    int car3 = Car.createCar(builder,10001L,88888L,id3);

    int[] cars = new int[3];
    cars[0]= car1;
    cars[1] = car2;
    cars[2] = car3;

    //创建Basic对象里面的Car集合
    int carList = Basic.createCarListVector(builder,cars);

    int name = builder.createString("jack");
    int email = builder.createString("[email protected]");
    int basic = Basic.createBasic(builder,10,name,email,100L,true,100,carList);
    int basicOffset = Items.createBasicVector(builder,new int[]{basic});
    Items.startItems(builder);
    Items.addItemId(builder,1000L);
    Items.addTimestemp(builder,2016);
    Items.addBasic(builder,basicOffset);

    int rootItems = Items.endItems(builder);
    Items.finishItemsBuffer(builder,rootItems);

    //============保存数据到文件=================
    File sdcard = Environment.getExternalStorageDirectory();
    //保存的路径
    File file = new File(sdcard,"Items.txt");
    if(file.exists()){
        file.delete();
    }
    ByteBuffer data = builder.dataBuffer();
    FileOutputStream out = null;
    FileChannel channel = null;
    try {
        out = new FileOutputStream(file);
        channel = out.getChannel();
        while(data.hasRemaining()){
            channel.write(data);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        try {
            if(out!=null){
                out.close();
            }
            if(channel!=null){
                channel.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//===================反序列化=============================
    FileInputStream fis = null;
    FileChannel readChannel = null;
    try {
        fis = new FileInputStream(file);
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        readChannel = fis.getChannel();
        int readBytes = 0;
        while ((readBytes=readChannel.read(byteBuffer))!=-1){
            System.out.println("读取数据个数:"+readBytes);
        }
        //把指针回到最初的状态,准备从byteBuffer当中读取数据
        byteBuffer.flip();
        //解析出二进制为Items对象。
        Items items = Items.getRootAsItems(byteBuffer);
        //读取数据测试看看是否跟保存的一致
        Log.i(TAG,"items.id:"+items.ItemId());
        Log.i(TAG,"items.timestemp:"+items.timestemp());

        Basic basic2 = items.basic(0);
        Log.i(TAG,"basic2.name:"+basic2.name());
        Log.i(TAG,"basic2.email:"+basic2.email());

        //carList
        int length = basic2.carListLength();
        for (int i=0;i

3.基本原理

网络传输优化----flatBuffer_第5张图片
原理图

FlatBuffers 保存在一个 byte 数组中,有一个“支点”指针(pivot point)以此为界,存储的内容分为两个部分:元数据和数据内容。其中元数据部分就是数据在前面,其长度等于对象中的字段数量,每个 byte 保存对应字段内容在数组中的索引(从支点位置开始计算)。

namespace com.race604.fbs;
enum FriendshipStatus: int {Friend = 1, NotFriend}
table Person {
name: string;
friendshipStatus: FriendshipStatus = Friend;
spouse: Person;
friends: [Person];
}
root_type Person;

上面的 Person 对象第一个字段是 name,其值的索引位置是 1,所以从索引位置 1 开始的字符串,就是 name 字段的值 "John"。第二个字段是 friendshipStatus,其索引值是 6,找到值为 2, 表示 NotFriend。第三个字段是 spouse,也一个 Person 对象,索引值是 12,指向的是此对象的支点位置。第四个字段是一个数组,图中表示的数组为空,所以索引值是 0。

你可能感兴趣的:(网络传输优化----flatBuffer)