zoukankan      html  css  js  c++  java
  • 使用flatbuffers

    问题

    张三是个java程序员,他写产生数据的程序.李四是个python程序员,他要用python处理张三产生的数据.最直观常用的方法就是张三用java把产生的数据保存成csv或者xml文件,然后李四用python读取csv或xml文件.这没有问题.但现在有一种性能更好的方法,flatbuffers.

    作用

    可以把flatbuffers理解成一个可执行文件flatc.这个可执行文件可以把表示数据格式的fbs文件转化成c++,java,python...代码.张三擅长使用java,他就用flatc把fbs文件转化成java代码.用转化好的java代码把数据存成flatbuffers的格式.李四用flatc把同样的fbs文件转化成自己熟悉的python代码,李四可以用这份python代码把flatbuffers格式文件中的数据读出来.这就实现了不同语言间传数据.当然这只是一个简单的使用场景.flatbuffers的作用远不只是这些.

    使用例子

    先写一个表示数据格式的文件school.fbs

    namespace school;
    
    table School {
        name:string;
        students:[Student];
    }
    
    table Student {
        number:short;
        name:string;
    }
    root_type School;
    

    具体的语法规则看参考资料,只简单的解释下.上面代码定义了一个根结点为School的数据.里面的student有2个成员变量number,name. School也有2个成员变量,一个是name代码school的名字.一个是Student的数组.
    然后执行下面命令:

    flatc.exe -p school.fbs
    

    会生成一堆python代码.再用生成的python创建一个flatbuffers文件,代码如下:

    # coding:utf-8
    from __future__ import print_function
    from __future__ import division
    
    import flatbuffers
    
    from school import School
    from school import Student
    
    builder = flatbuffers.Builder(1024)
    
    stu1 = builder.CreateString('zhang3')
    stu2 = builder.CreateString('li4')
    
    Student.StudentStart(builder)
    Student.StudentAddName(builder, stu1)
    Student.StudentAddNumber(builder, 3)
    zhang3 = Student.StudentEnd(builder)
    
    Student.StudentStart(builder)
    Student.StudentAddName(builder, stu2)
    Student.StudentAddNumber(builder, 4)
    li4 = Student.StudentEnd(builder)
    
    School.SchoolStartStudentsVector(builder, 2)
    builder.PrependUOffsetTRelative(li4)
    builder.PrependUOffsetTRelative(zhang3)
    students = builder.EndVector(2)
    
    School.SchoolStart(builder)
    School.SchoolAddStudents(builder, students)
    school_result = School.SchoolEnd(builder)
    
    builder.Finish(school_result)
    
    buf = builder.Output()
    
    new_school = School.School.GetRootAsSchool(buf, 0)
    print(new_school.Students(0).Name())
    print(new_school.Students(0).Number())
    print(new_school.Students(1).Name())
    print(new_school.Students(1).Number())
    
    with open("result.bin", mode="wb") as f:
        f.write(buf)
    

    这段代码的作用是新建2个student,一个zhang3,一个li4,然后把student数据保存到School里,最后生成文件result.bin. result.bin就是flatbuffers格式的文件,本质下就是二进制文件.
    再执行下面命令:

    flatc.exe -j school.fbs
    

    生成一堆java代码.可以用java代码把result.bin文件中的数据读出来.代码如下:

    package com.company;
    import school.School;
    
    import java.io.*;
    import java.nio.ByteBuffer;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
        private void process() {
            Path path = Paths.get("D:\yourpath\result.bin");
            try {
                byte[] data =  Files.readAllBytes(path);
                ByteBuffer buf = java.nio.ByteBuffer.wrap(data);
                School school = School.getRootAsSchool(buf);
                System.out.println(school.students(0).name());
                System.out.println(school.students(0).number());
                System.out.println(school.students(1).name());
                System.out.println(school.students(1).number());
            } catch (IOException e) {
                System.out.println("IOException");
            }
    
        }
    
        public static void main(String[] args) {
            Main m = new Main();
            m.process();
        }
    }
    

    另一个名字

    google在tensorflow lite中把result.bin这类二进制文件起一个高大上的名字——tflite

    参考资料

    1. FlatBuffers Documentation
    2. flatbuffers源代码
  • 相关阅读:
    STDMETHOD_,STDMETHOD,__declspec(novtable)和__declspec(selectany)
    __stdcall 与 __cdecl
    winows 进程通信的实例详解
    Windows 下多线程编程技术
    MFC/VC++ UI界面美化技术
    VC++中 wstring和string的互相转换实现
    VS2010项目转化为VS2008项目
    VC++ 响应回车键的2种方法
    高效 告别996,开启java高效编程之门 2-4实战:单一条件参数化
    高效 告别996,开启java高效编程之门 2-3实战:硬编码业务逻辑
  • 原文地址:https://www.cnblogs.com/zhouyang209117/p/8087258.html
Copyright © 2011-2022 走看看