You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中FlatBuffers结构体向量序列化示例求助

完整Java FlatBuffers结构体向量实现示例

我完全懂你的困扰——官方教程那段代码只展示了向量构建的核心部分,却跳过了最基础的初始化步骤,很容易让人卡壳。下面我给你一个完整的、可直接运行的Java示例,把从schema定义到序列化、反序列化的全流程都讲清楚。

第一步:定义FlatBuffers Schema

首先你需要先写一个.fbs schema文件(比如命名为monster.fbs),用来定义结构体Vec3和包含向量的Monster表:

struct Vec3 {
  x: float;
  y: float;
  z: float;
}

table Monster {
  path: [Vec3]; // 这里就是结构体向量的定义
}

root_type Monster; // 指定根类型为Monster

然后用FlatBuffers的flatc工具生成Java代码:

flatc --java monster.fbs

执行后会生成对应的Vec3.java和Monster.java文件,直接导入你的项目即可。

第二步:完整Java代码实现

下面是包含FlatBufferBuilder初始化、向量构建、序列化和反序列化的完整代码:

import com.google.flatbuffers.FlatBufferBuilder;

public class FlatBuffersVectorDemo {
    public static void main(String[] args) {
        // 初始化FlatBufferBuilder(也就是你提到的fbb)
        // 参数是初始缓冲区大小,1024是常用值,内部会自动扩容
        FlatBufferBuilder fbb = new FlatBufferBuilder(1024);

        // -------------------------- 构建结构体向量 --------------------------
        // 1. 启动向量:参数是builder和向量的长度
        Monster.startPathVector(fbb, 2);
        // 2. 添加向量元素:注意FlatBuffers是逆序添加,endVector会自动反转成正序
        Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f);
        Vec3.createVec3(fbb, 4.0f, 5.0f, 6.0f);
        // 3. 结束向量构建,得到向量的偏移量
        int pathVectorOffset = fbb.endVector();

        // -------------------------- 构建根表Monster --------------------------
        Monster.startMonster(fbb);
        Monster.addPath(fbb, pathVectorOffset); // 将向量关联到Monster表
        int monsterOffset = Monster.endMonster(fbb);

        // -------------------------- 完成序列化 --------------------------
        fbb.finish(monsterOffset); // 传入根节点偏移量,完成整个Buffer的序列化

        // -------------------------- 反序列化验证 --------------------------
        // 从ByteBuffer中解析出Monster对象
        Monster monster = Monster.getRootAsMonster(fbb.dataBuffer());

        // 读取并打印向量内容
        System.out.println("Path vector contains " + monster.pathLength() + " elements:");
        for (int i = 0; i < monster.pathLength(); i++) {
            Vec3 vec = monster.path(i);
            System.out.printf("Element %d: x=%.1f, y=%.1f, z=%.1f%n", i+1, vec.x(), vec.y(), vec.z());
        }
    }
}

关键细节说明

  • FlatBufferBuilder的创建:new FlatBufferBuilder(初始大小)是标准初始化方式,初始大小可以根据你的数据预估,不够的话内部会自动扩容,不用太纠结具体数值。
  • 向量构建顺序:虽然我们是先添加(1,2,3)再添加(4,5,6),但FlatBuffers会在endVector()时自动反转元素顺序,最终反序列化出来的是正序的,所以不用手动逆序添加。
  • 动态向量的构建:如果向量长度不是固定的(比如从集合中读取数据),可以先收集所有结构体的偏移量,再逆序添加:
import java.util.ArrayList;
import java.util.List;

// 示例:动态构建向量
List<Integer> vecOffsets = new ArrayList<>();
vecOffsets.add(Vec3.createVec3(fbb, 7.0f, 8.0f, 9.0f));
vecOffsets.add(Vec3.createVec3(fbb, 10.0f, 11.0f, 12.0f));

Monster.startPathVector(fbb, vecOffsets.size());
// 逆序添加偏移量
for (int i = vecOffsets.size() - 1; i >= 0; i--) {
    fbb.addOffset(vecOffsets.get(i));
}
int dynamicPathOffset = fbb.endVector();

运行结果

执行上面的代码后,你会看到如下输出:

Path vector contains 2 elements:
Element 1: x=1.0, y=2.0, z=3.0
Element 2: x=4.0, y=5.0, z=6.0

内容的提问来源于stack exchange,提问作者shanker861

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:12:38