FlatBuffers schema 中如何声明 file_identifier 与 file_extension 用于二进制文件格式?
2026/9/13 17:18:29 网站建设 项目流程

FlatBuffers schema 中如何声明 file_identifier 与 file_extension 用于二进制文件格式?

【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers

FlatBuffer 的二进制 buffer 默认不是自描述的:解析它之前你必须知道对应的 schema。如果你的使用方式是把它存成磁盘上的文件,就需要一种"魔数"来做 sanity check,确认读到的确实是期望的那种文件。FlatBuffers 内置了file_identifier声明,可以以极小的空间代价给 buffer 加上标识,并保持与不带标识的 buffer 兼容;同时可以用file_extension改掉flatc生成二进制文件时的默认.bin扩展名。本文介绍如何在.fbsschema 中声明这两者,并用flatc生成、验证二进制文件。

前提是你已经构建好flatc编译器(构建方式见 docs/source/quick_start.md,文档给出的是cmake -G "Unix Makefiles"+make -j),并且手上有一个带root_type的 schema。仓库里的 samples/monster.fbs 就是一个典型的 schema 示例(它未声明file_identifier,正好可以作为对比)。

在 schema 中声明 file_identifier

按照 docs/source/schema.md 的 "File identification and extension" 一节,在 schema 中像写root_type一样声明:

file_identifier "MYFI";

约束只有一条:标识必须是恰好 4 个字符。这 4 个字符最终会落在 buffer 偏移 4–7(含两端)的字节上。仓库测试 schema dart/test/monster_test.fbs 中就有真实用法file_identifier "MONS";

语法层面,docs/source/grammar.md 的 EBNF 定义了两条顶层声明:

file_extension_decl = `file_extension` string_constant `;` file_identifier_decl = `file_identifier` string_constant `;`

即两者都是 schema 顶层声明,参数是一个字符串常量,以分号结束。

在 schema 中声明 file_extension

flatc默认把二进制数据文件输出为.bin后缀。如果希望改成自己的格式名,在 schema 中声明:

file_extension "ext";

samples/monster.fbs这类 schema 没有声明file_extensionflatc就会沿用默认的.bin;声明后生成的数据文件名改为<数据名>_wire.extext换成你声明的值)。

用 flatc 生成带标识的二进制文件

对有file_identifier的 schema,flatc会自动把标识写入它生成的所有二进制(-b),不需要额外参数。按 docs/source/flatc.md 的用法,把mydata.jsonmyschema.fbs序列化为二进制:

flatc --binary myschema.fbs mydata.json

这会生成一个mydata_wire.bin文件(扩展名按file_extension声明决定)。注意 schema 文件必须列在数据文件之前。

同样的机制也作用于 C++ 生成的代码:schema 带标识时,FinishMonsterBuffer这类生成出来的完成函数会自动写入标识;如果你就是想生成不带标识的 buffer,显式调用FlatBufferBuilder::Finish即可绕过。

验证标识是否写入 buffer

文档给出的验证方式分两种:

  1. 代码层面:加载 buffer 后调用生成代码里的MonsterBufferHasIdentifier(根表名替换为你的root_type名字)检查标识是否存在。C++ 底层对应 include/flatbuffers/buffer.h 中的两个内联函数:GetBufferIdentifier(buf)返回 buffer 中标识字节的指针(位于根偏移之后;size-prefixed buffer 则多一个sizeof(uoffset_t)前缀),BufferHasIdentifier(buf, identifier)判断标识值是否符合预期。
  2. 命令行层面:把二进制转回 JSON 做往返检查:
flatc --json myschema.fbs -- mydata.bin

这条命令能成功的前提与file_identifier直接相关:如果 schema没有定义file_identifier,就必须额外加--raw-binary选项才能读取;而--raw-binary允许读取不带标识的二进制,文档同时警告:schema 与数据不匹配时它可能让flatc崩溃。也就是说,声明了file_identifier后,标识本身就充当了flatc读取二进制前的一道类型校验。

使用边界

  • 标识只占 4 字节,且 buffer 与不带标识的旧 buffer 保持兼容;文档建议它用于文件这类开放式场景。如果只是想在一组固定的网络消息中区分类型,用 union 更合适。
  • file_identifier不改变root_type的语义,两者相互独立:root_type声明序列化数据的根表(对 JSON 解析尤其重要),file_identifier只是给 buffer 加魔数。
  • --raw-binary是给不带标识的 buffer 的兜底读取路径,存在 schema 错配即崩溃的风险,不要把它当作常规读取方式。

完成以上声明并跑通flatc --binary/flatc --json往返后,你的 schema 生成的二进制文件就具备了魔数校验和自定义扩展名,可以作为独立的文件格式使用。

【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询