- FlatBuffers 教程
- FlatBuffers - 首页
- FlatBuffers - 简介
- FlatBuffers - Schema
- FlatBuffers - 结构
- FlatBuffers - 表
- FlatBuffers - 字符串
- FlatBuffers - 数字
- FlatBuffers - 布尔值
- FlatBuffers - 枚举
- FlatBuffers - 向量
- FlatBuffers - 结构体
- FlatBuffers - 联合体
- FlatBuffers - 嵌套表
- FlatBuffers - 默认值
- FlatBuffers - JSON 转二进制
- FlatBuffers - 二进制转 JSON
- FlatBuffers - 可变缓冲区
- FlatBuffers - 向后兼容性
- FlatBuffers - 语言无关性
- FlatBuffers 有用资源
- FlatBuffers 快速指南
- FlatBuffers - 有用资源
- FlatBuffers - 讨论
FlatBuffers 快速指南
FlatBuffers - 简介
在深入了解 FlatBuffers 之前,让我们先简要回顾一下序列化,这是 FlatBuffers 所做的工作。
什么是序列化和反序列化?
每当我们需要将对象状态持久化到内存系统时,都需要序列化。在序列化中,我们将对象转换为字节,并将这些字节存储在内存系统中。这些存储的字节随后可以被反序列化以恢复对象状态。由于我们将对象转换为字节,因此可以将其存储在任何地方,包括文件系统、消息队列、数据库等等,然后我们可以将这些字节传输到不同的机器并检索对象状态。
为什么我们需要序列化和反序列化?
序列化有助于持久化对象状态,然后我们可以将其传输到网络上的任何位置。接收后,我们可以反序列化对象,或者换句话说,我们可以随时在不同的机器上从字节恢复我们的对象。这是序列化和反序列化的许多重要用例之一。另一个重要用例是对象需要通过网络传输的情况。消息队列、数据库对象、REST API 都遵循此原则。在这种情况下,发送方首先序列化对象,然后将其传输到接收方。接收方然后反序列化已序列化的对象。
在 REST API、微服务架构中,应用程序通常被分解成小的服务,这些服务通过消息队列和 API 相互通信。由于通信是通过网络进行的,需要频繁地将对象转换为字节,然后再转换回对象。因此,序列化和反序列化在分布式环境中变得非常关键。
为什么选择 FlatBuffers?
Google FlatBuffers 执行将对象序列化和反序列化为字节的操作,这些字节可以跨网络传输。但也有一些其他的库和机制可以传输数据。
那么,是什么让 FlatBuffers 如此特别呢?以下是一些重要的特性:
语言无关性 - FlatBuffers 编译器可以为多种语言创建代码,例如 Java、Python、Go、C、C++ 等。因此,Java 对象可以由 Java 程序序列化为字节,并且可以反序列化为 Python 对象,反之亦然。
高效的数据压缩 - FlatBuffers API 最初是为游戏环境和性能关键型系统开发的,其设计考虑了数据压缩和性能。它非常节省内存,甚至比 Google Protocol Buffers(另一个 Google 序列化和反序列化库)更快。
向前和向后兼容性 - FlatBuffers 架构同时具有向前和向后兼容性。FlatBuffers 的 schema 支持在较新代码中添加更改,并允许弃用较旧的更改,而不会破坏向后兼容性。
易于使用 - FlatBuffers 库自动生成序列化代码(我们将在接下来的章节中看到),具有版本控制方案,以确保数据创建者和数据使用者可以拥有序列化定义的不同版本等。
JSON 可转换 FlatBuffers schema 文件可以转换为 JSON 文件,同样,我们可以使用 FlatBuffers schema 转换 JSON 文件。
FlatBuffers 与其他方案对比 (XML/JSON/Java 序列化)
让我们看看其他通过网络传输数据的方式与 FlatBuffers 相比如何。
特性 | FlatBuffers | JSON | XML |
---|---|---|---|
语言无关性 | 是 | 是 | 是 |
序列化数据大小 | 三者中最小的 | 小于 XML | 三者中最大的 |
人类可读性 | 否,因为它使用单独的编码 schema | 是,因为它使用基于文本的格式 | 是,因为它使用基于文本的格式 |
序列化速度 | 三者中最快 | 快于 XML | 三者中最慢 |
数据类型支持 | 比其他两者更丰富。支持复杂数据类型,如 Any、oneof 等。 | 支持基本数据类型 | 支持基本数据类型 |
对演变 schema 的支持 | 是 | 否 | 否 |
FlatBuffers - Schema
概述
现在让我们使用 Google FlatBuffers 并看看它如何与一个简单的问候应用程序一起工作。在这个例子中,我们将创建一个简单的应用程序,它将执行以下操作:
问候写入器
从用户处获取问候语和用户名
将上述信息存储在磁盘上的文件中
问候读取器
读取我们在上面存储的文件
将数据转换为对象并打印数据
FlatBuffers Schema 文件
FlatBuffers 的“schema 文件”包含我们要序列化的数据的 schema 定义。数据存储在具有扩展名“.fbs” 的人类可读文件中。
让我们将以下数据存储在greeting.fbs中,我们将在我们的第一个应用程序中使用它。
greeting.fbs
namespace com.tutorialspoint.greeting; table Greet { greeting: string; username: string; } root_type Greet;
理解每个结构
namespace com.tutorialspoint.greeting;
这里的namespace用于.fbs文件生成的代码的包/命名空间声明。例如,我们生成的 Java 类将位于 com.tutorialspoint.greeting 包中。
table Greet
要创建/重新创建的对象的基础类的名称。
greeting: string; username: string;
这些是Greet类的属性以及数据类型。
root_type Greet;
root_type 告诉 FlatBuffers 编译器根表是 Greet,它将是生成代码时的主类。
FlatBuffers 代码生成
现在我们已经定义了,让我们安装“flatc”二进制文件,我们将使用它来自动生成上述Greet类的代码。二进制文件可以在"https://github.com/google/flatbuffers/releases"找到。
根据操作系统选择正确的二进制文件。我们将在 Windows 上安装 FlatBuffers 编译器二进制文件,但 Linux 的步骤差别不大。
我们已下载https://github.com/google/flatbuffers/releases/download/v24.3.25/Windows.flatc.binary.zip
验证 FlatBuffers 编译器设置
安装后,确保您可以通过命令行访问它:
flatc --version flatc version 24.3.25
这确认 Flatc 已正确安装。现在让我们继续为 Java 创建上面描述的问候应用程序。
Java 中的问候应用程序
现在我们已经安装了flatc,我们可以使用flatc从 .fbs 文件自动生成代码。让我们首先创建一个 Java 项目。
以下是我们将用于 Java 项目的 Maven 配置。请注意,它还包含flatc-java所需的库。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tutorialspoint.greeting</groupId> <artifactId>flatbuffers-tutorial</artifactId> <version>1.0</version> <packaging>jar</packaging> <properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/com.google.flatbuffers/flatbuffers-java --> <dependency> <groupId>com.google.flatbuffers</groupId> <artifactId>flatbuffers-java</artifactId> <version>24.3.25</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <configuration> <!--Put your configurations here--> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
我们所有的代码都将位于src/main/java下。
项目结构搭建完毕后,让我们生成Greet类的代码:
生成 Java 类
flatc --java greeting.fbs
命令执行后,您会在当前目录中的com > tutorialspoint > greeting文件夹下看到一个自动生成的类。
Greet.java
此文件包含一个Greet类,它将帮助我们对Greet对象进行序列化和反序列化。
使用生成的 Java 类
现在,让我们编写数据的写入器,它将接受用户名和问候语作为输入:
GreetWriter.java
package com.tutorialspoint.greeting; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class GreetWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Greet FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // read greeting and username from console int greeting = builder.createString(args[0]); int username = builder.createString(args[1]); // create Greet FlatBuffers using startGreet() method Greet.startGreet(builder); // add the greeting and username to the Greet FlatBuffer Greet.addGreeting(builder, greeting); Greet.addUsername(builder, username); // mark end of data being entered in Greet FlatBuffer int greet = Greet.endGreet(builder); // finish the builder builder.finish(greet); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "greeting_flatbuffers_output"; System.out.println("Saving greeting to file: " + filename); // write the builder content to the file named greeting_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved greeting with following data to disk: \n" + greeting); } }
该写入器简单地获取 CLI 参数,创建Greet对象,将其序列化,然后将其转储到文件中。
现在让我们编写一个读取器来读取文件:
GreetReader.java
package com.tutorialspoint.greeting; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class GreetReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "greeting_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Greet greet = Greet.getRootAsGreet(buf); // print greet values System.out.println("Greeting: " + greet.greeting() + "\n" + "Username: " + greet.username()); } } }
该读取器简单地从同一文件中读取,将其反序列化,并打印问候信息。
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,让我们首先执行写入器将对象序列化到文件系统。
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.greeting.GreetWriter Hello John Saving greeting to file: greeting_protobuf_output Saved greeting with following data to disk: 12
反序列化已序列化的对象
然后,让我们执行读取器从文件系统反序列化对象。
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.greeting.GreetReader Reading from file greeting_protobuf_output Greeting: Hello Username: John
因此,正如我们看到的,写入器序列化并保存到文件的数据,被读取器正确地反序列化并相应地打印出来。
FlatBuffers - 结构
概述
现在让我们看看 Google FlatBuffers 提供的一些基本数据结构和数据类型。我们将使用电影院的例子来查看这些数据结构。
请注意,对于此结构,虽然我们将使用 Java 代码,但在 Python 代码中使用它们也应该同样简单且可行。
在接下来的几章中,我们将逐一讨论以下 FlatBuffers 数据类型:
数据类型
表 (table) - “表”是 FlatBuffers 的一个非常基本的基础构件。它在我们使用的语言(例如 Java、Python 等)中转换为类
字符串 (string) - “字符串”数据类型在我们使用的语言(例如 Java、Python 等)中转换为字符串
数字 (Numbers) - 数字包括 FlatBuffers 类型,如 int、short、float、double,它们是 Protobuf 的基本构建块。它在我们使用的语言(例如 Java、Python 等)中分别转换为 int、long、float、double。我们也可以使用别名,如 int16 代表 short,float32 代表 float 等。
布尔值 (bool) - “布尔值”数据类型是 FlatBuffers 的基本构建块之一。它在我们使用的语言(例如 Java、Python 等)中转换为布尔值。
枚举 (enum) − “enum” 是 FlatBuffers 的复合数据类型之一。它在我们使用的语言中被翻译成枚举,例如 Java。
向量 (vector) − 使用 [] 符号创建向量或数组,它是 FlatBuffers 的复合数据类型之一。FlatBuffers 向量类似于 Java 数组。
结构体 (struct) − “struct” 是 FlatBuffers 的复合数据类型之一。它用于创建不可修改的标量值集合。struct 使用更少的内存,并且查找速度非常快。
嵌套类 − 我们可以将使用 "table" 创建的类嵌套在另一个 "table" 中,从而创建嵌套类。
联合体 (union) − “union” 用于创建一个可以接受任何不同类型值的结构。
FlatBuffers - 表
概述
FlatBuffers 的最基本构建块是表 (table) 属性。这相当于我们在使用的语言中的类 (class),例如 Java、Python 等。
示例代码
以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建给定表的实例:
namespace com.tutorialspoint.theater; table Theater { } root_type Theater;
我们将以上内容保存到“theater.fbs”中,并在我们探索其他数据结构时使用它。
解释
namespace com.tutorialspoint.theater;
此参数特定于 Java,即“.fbs”文件生成的代码所在的包。Theater 类将创建在com.tutorialpoint.theater包中。
接下来,我们创建一个表 Theater:
table Theater
这只不过是将要创建/重新创建的对象的基类的类名。请注意,它在当前形式下是无用的,因为它没有任何其他属性。但是,随着我们的推进,我们将添加更多属性。
使用多个 table 属性
单个 fbs 文件也可以包含多个表。例如,如果需要,我们可以在同一个文件中添加一个Visitor表。FlatBuffers 将确保 Theater 类使用 root_type 属性保持为主类。例如:
namespace com.tutorialspoint.theater; table Theater { } table Visitor { } root_type Theater;
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flat --java theater.fbs
使用从 fbs 文件创建的 Java 类
就是这样!以上命令应该在当前目录中创建所需的文件,现在我们可以在 Java 代码中使用它们:
// Create a FlatBuffer Builder with default buffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // Create Theater FlatBuffers using startTheater() method Theater.startTheater(builder);
在这个阶段,它不是很有用,因为我们还没有向表中添加任何属性。当我们在Flat Buffers - string章节中查看字符串时,我们将进行此操作。
FlatBuffers - 字符串
概述
FlatBuffers 字符串在我们使用的语言中被翻译成字符串,例如 Java、Python 等。继续theater示例,以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建一个字符串:
theater.fbs
namespace com.tutorialspoint.theater; table Theater { name:string; address:string; } root_type Theater;
现在我们的表包含两个字符串属性。每个属性的默认值为 null。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
首先,让我们创建一个写入器 (writer)来写入theater信息:
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); int name = builder.createString("Silver Screener"); int address = builder.createString("212, Maple Street, LA, California"); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add the name and address to the Theater FlatBuffer Theater.addName(builder, name); Theater.addAddress(builder, address); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Name: " + theater.name() + "\n" + "Address: " + theater.address()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 72
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Name: Silver Screener Address: 212, Maple Street, LA, California
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为Theater对象来读取序列化后的字符串。在下一章Flat Buffers - Numbers中,我们将了解数字。
FlatBuffers - 数字
概述
数字包括 flatbuffers 类型,如int、short、float、double,它们是 FlatBuffers 的基本构建块。它们分别在我们使用的语言中被翻译成int、short、float、double,例如 Java、Python 等。
继续我们来自Flat Buffers - String章节的theater示例,以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建数字:
theater.fbs
namespace com.tutorialspoint.theater; table Theater { total_capcity:int; mobile:long; base_ticket_price:float; } root_type Theater;
现在我们的表包含数值属性。默认值为 0 或 0.0(视情况而定)。
从 FBS 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
<使用从 fbs 文件创建的 Java 类
首先,让我们创建一个写入器 (writer)来写入theater信息:
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); int totalCapacity = 320; long mobile = 98234567189L; float baseTicketPrice = 22.45f; // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addTotalCapcity(builder, totalCapacity); Theater.addMobile(builder, mobile); Theater.addBaseTicketPrice(builder, baseTicketPrice); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Total Capacity: " + theater.totalCapcity() + "\n" + "Mobile: " + theater.mobile() + "\n" + "Base Ticket Price: " + theater.baseTicketPrice()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 24
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Total Capacity: 320 Mobile: 98234567189 Base Ticket Price: 22.45
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为Theater对象来读取序列化后的字符串。在下一章Flat Buffers - bool中,我们将了解数字。
FlatBuffers - 布尔值
概述
bool数据类型是 FlatBuffers 的基本构建块之一。它在我们使用的语言中被翻译成Boolean,例如Java、Python等。
继续我们来自Flat Buffers - String章节的theater示例,以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建bool:
theater.fbs
namespace com.tutorialspoint.theater; table Theater { drive_in:bool; } root_type Theater;
现在我们的表包含一个bool属性。默认值为 false。
从 FBS 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); boolean driveIn = true; // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addDriveIn(builder, driveIn); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Drive In: " + theater.driveIn()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 8
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Drive In: true
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为Theater对象来读取序列化后的字符串。在下一章Flat Buffers - Enum中,我们将了解数字。
FlatBuffers - 枚举 (enum)
概述
枚举 (enum)数据类型是 FlatBuffers 的复合数据类型之一。它相当于在我们使用的语言中的枚举 (enum),例如Java等。
继续我们来自Flat Buffers - String章节的theater示例,以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建一个枚举 (enum):
theater.fbs
namespace com.tutorialspoint.theater; enum PAYMENT_SYSTEM: byte { CASH = 0, CREDIT_CARD = 1, DEBIT_CARD, APP = 3 } table Theater { payment:PAYMENT_SYSTEM; } root_type Theater;
现在我们的表包含一个枚举 (enum)属性。我们为每个枚举常量分配了一个值,除了 DEBIT_CARD,它默认取增量值 2。
我们定义了枚举 (enum),并在下面将其用作数据类型以及“payment”属性。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 和 PAYMENT_SYSTEM 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addPayment(builder, PAYMENT_SYSTEM.DEBIT_CARD); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Payment Method: " + theater.payment()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器 (writer):
> java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater information to file: theater_flatbuffers_output Saved theater information with following data to disk: 8
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Payment Method: 2
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为Theater对象来读取序列化后的枚举 (enum)。在下一章Protocol Buffers - Vector中,我们将了解向量,一种复合类型。
FlatBuffers - 向量
概述
向量 (Vector)数据类型是 FlatBuffers 的复合数据类型之一。它相当于在我们使用的语言中的数组 (array)或列表 (List),例如Java等。
继续我们来自Flat Buffers - String章节的theater示例,以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建一个向量 (vector):
theater.fbs
namespace com.tutorialspoint.theater; table Theater { snacks:[string]; // vector of strings tickets:[float]; // vector of floats } root_type Theater;
现在我们的表包含字符串和浮点数的向量 (vector)属性。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
创建和写入向量
为了创建一个向量,我们需要首先准备标量类型数组的偏移量,然后我们可以将向量添加到 flat buffer 中。
// create data for an array of strings int popcorn = builder.createString("Popcorn"); int coke = builder.createString("Coke"); int chips = builder.createString("Chips"); int soda = builder.createString("Soda"); // create array for snacks int[] snacks = {popcorn, coke, chips, soda}; // create offset for snacks vector int snacksVector = Theater.createSnacksVector(builder, snacks); // add details to the Theater FlatBuffer Theater.addSnacks(builder, snacksVector);
以下示例代码展示了创建字符串和整数向量的过程。
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // create data for an array of strings int popcorn = builder.createString("Popcorn"); int coke = builder.createString("Coke"); int chips = builder.createString("Chips"); int soda = builder.createString("Soda"); // create array for snacks int[] snacks = {popcorn, coke, chips, soda}; // create array for tickets float[] tickets = {100.0f, 100.f, 200.f}; // create offset for snacks vector int snacksVector = Theater.createSnacksVector(builder, snacks); // create offset for tickets vector int ticketsVector = Theater.createTicketsVector(builder, tickets); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addSnacks(builder, snacksVector); Theater.addTickets(builder, ticketsVector); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
读取向量
为了读取向量,我们有方法来获取向量的长度并通过索引获取条目,如下所示。
// iterate snacks vector of length determined by snacksLength() method for(int i = 0; i < theater.snacksLength(); i++ ) { // get a snack by its index System.out.print(" " + theater.snacks(i)); }
以下示例代码展示了读取字符串和整数向量的过程。
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Snacks: "); for(int i = 0; i < theater.snacksLength(); i++ ) { System.out.print(" " + theater.snacks(i)); } System.out.println("\nTickets: "); for(int i = 0; i < theater.ticketsLength(); i++ ) { System.out.print(" " + theater.tickets(i)); } } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器 (writer):
> java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater information to file: theater_flatbuffers_output Saved theater information with following data to disk: 96
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Snacks: Popcorn Coke Chips Soda Tickets: 100.0 100.0 200.0
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为Theater对象来读取序列化后的向量 (vector)。在下一章Flat Buffers - struct中,我们将了解结构体,一种复合类型。
FlatBuffers - 结构体 (struct)
概述
结构体 (struct)数据类型是 FlatBuffers 的复合数据类型之一。它用于创建不可变的数据结构。结构体占用更少的内存,查找速度很快。结构体通常是标量类型的组合。
继续我们来自Flat Buffers - String章节的theater示例,以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建一个结构体 (struct):
theater.fbs
namespace com.tutorialspoint.theater; struct Position { x: int; y: int; z: int; } table Theater { location: Position; } root_type Theater;
现在我们的表包含定义为 Position 类型的 location 属性。Position 是一个结构体,用于定义三个整数的数据结构。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建Theater和Position类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
创建和写入结构体
为了创建一个结构体,我们需要首先准备标量类型数组的偏移量,然后我们可以将向量添加到 flat buffer 中。
// create offset for location struct int location = Position.createPosition(builder, 100, 110, 120); // add details to the Theater FlatBuffer Theater.addLocation(builder, location);
以下示例代码展示了创建整数结构体的过程。
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // create offset for location struct int location = Position.createPosition(builder, 100, 110, 120); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addLocation(builder, location); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
读取结构体
为了读取结构体,我们有方法来获取结构体的每个值。
Position position = theater.location(); System.out.println("x: " + position.x()); System.out.println("y: " + position.y()); System.out.println("z: " + position.z());
以下示例代码展示了读取整数结构体的过程。
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Location: "); Position position = theater.location(); System.out.println("x: " + position.x()); System.out.println("y: " + position.y()); System.out.println("z: " + position.z()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器 (writer):
> java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater information to file: theater_flatbuffers_output Saved theater information with following data to disk: 16
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Location: x: 100 y: 110 z: 120
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为Theater对象来读取序列化后的结构体 (struct)。在下一章Flat Buffers - union中,我们将了解联合体,一种复合类型。
FlatBuffers - 联合体 (union)
概述
联合体 (union)数据类型是 FlatBuffers 的复合数据类型之一。它用于创建灵活的数据结构,可以采用任何所需类型。
继续我们来自Flat Buffers - String章节的theater示例,以下是我们需要使用的语法,用于指示 FlatBuffers 我们将创建一个联合体 (union):
theater.fbs
namespace com.tutorialspoint.theater; union People { Employee, Viewer } table Theater { people: People; } table Employee { name:string; address:string; id: int; } table Viewer { name: string; address: string; } root_type Theater;
现在我们的表包含定义为两个表 Employee 和 Viewer 的 People 属性。在 Theater 表中,我们定义了联合类型的 people,这意味着我们可以将 Employee 或 Viewer 中的任何一个存储在 people 变量中。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建Theater、People、Employee和Viewer类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
创建和写入联合体
为了创建一个联合体,我们需要首先准备所需类型的偏移量,例如 Viewer,然后我们可以将 Viewer 与其类型一起添加到 flat buffer 中。
// create offset for Viewer int viewerName = builder.createString("Mery"); int viewerAddress = builder.createString("Avenue 4"); int viewer = Viewer.createViewer(builder, viewerName, viewerAddress); //add union tyoe Theater.addPeopleType(builder, People.Viewer); // add details to the Theater FlatBuffer Theater.addPeople(builder, viewer);
以下示例代码展示了创建联合体的过程。
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // create offset for Viewer int viewerName = builder.createString("Mery"); int viewerAddress = builder.createString("Avenue 4"); int viewer = Viewer.createViewer(builder, viewerName, viewerAddress); // create offset for vector //int people = Theater.createPeople // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); //add union type Theater.addPeopleType(builder, People.Viewer); // add details to the Theater FlatBuffer Theater.addPeople(builder, viewer); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
读取联合体
为了读取一个联合体(Union),我们可以检查联合体对象的类型,然后相应地检索值。
// get the saved union type int unionType = theater.peopleType(); // if union is of type Viewer if(unionType == People.Viewer) { Viewer viewer = (Viewer)theater.people(new Viewer()); System.out.println("Name: " + viewer.name()); System.out.println("Address: " + viewer.address()); } // if union is of type Employee else if(unionType == People.Employee) { Employee employee = (Employee)theater.people(new Employee()); System.out.println("Name: " + employee.name()); System.out.println("Address: " + employee.address()); System.out.println("Id: " + employee.id()); }
下面的示例代码展示了读取联合体的过程。
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("People: "); // get the type of union int unionType = theater.peopleType(); // if union is of Viewer type if(unionType == People.Viewer) { Viewer viewer = (Viewer)theater.people(new Viewer()); System.out.println("Name: " + viewer.name()); System.out.println("Address: " + viewer.address()); } else if(unionType == People.Employee) { Employee employee = (Employee)theater.people(new Employee()); System.out.println("Name: " + employee.name()); System.out.println("Address: " + employee.address()); System.out.println("Id: " + employee.id()); } } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器 (writer):
> java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater information to file: theater_flatbuffers_output Saved theater information with following data to disk: 60
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output People: Name: Mery Address: Avenue 4
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为**Theater**对象来读取序列化的**struct**。在下一章Flat Buffers - 嵌套表中,我们将了解复合类型嵌套表。
FlatBuffers - 嵌套表
概述
在这里,我们将学习如何在 Flat Buffers 中创建嵌套表。它相当于一个嵌套的**Java**类。
继续我们从Flat Buffers - 字符串章节中的**theater**示例,以下是我们需要使用的语法,以便指示 FlatBuffers 我们将创建一个**嵌套表**:
theater.fbs
namespace com.tutorialspoint.theater; table Theater { owner: TheaterOwner; } table TheaterOwner { name:string; address:string; } root_type Theater;
现在我们的**Theater**表包含一个嵌套表,即关于剧院所有者的信息。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录的**com > tutorialspoint > theater**文件夹中创建一个 Theater 和 TheaterOwner 类。我们在应用程序中使用此类,与Flat Buffers - 模式章节中所做的一样。
使用从 fbs 文件创建的 Java 类
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // create offset for TheaterOwner int ownerName = builder.createString("Mery"); int ownerAddress = builder.createString("Avenue 4"); int owner = TheaterOwner.createTheaterOwner(builder, ownerName, ownerAddress); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addOwner(builder, owner); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Owner Details: "); TheaterOwner owner = theater.owner(); System.out.println("Name: " + owner.name()); System.out.println("Address: " + owner.address()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 56
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Owner Details: Name: Mery Address: Avenue 4
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为**Theater**对象来读取序列化的嵌套表/对象。
FlatBuffers - 默认值
概述
我们在之前的示例中已经看到了如何在 Flat Buffers 中序列化和反序列化各种类型。如果我们没有指定任何值,则会存储默认值。如果我们为变量指定相同的默认值,则 FlatBuffers 不会分配额外的空间。
Flat Buffers 支持其数据类型的默认值,如下表所示:
数据类型 | 默认值 |
---|---|
int16 / short / int / long | 0 |
Float/double | 0.0 |
字符串 | 空字符串 |
布尔值 | False |
枚举 | 第一个枚举项,即“index=0”的项 |
向量 | 空列表 |
嵌套类 | null |
因此,如果用户没有为这些数据类型指定数据,则它们将采用上述默认值。现在,让我们继续我们的**theater**示例来演示它的工作原理。
在这个示例中,我们将让所有字段都使用默认值。唯一指定的字段将是剧院的名称。
继续我们从Flat Buffers - 字符串章节中的**theater**示例,以下是我们需要使用的语法,以便指示 FlatBuffers 我们将创建各种数据类型:
theater.fbs
namespace com.tutorialspoint.theater; enum PAYMENT_SYSTEM: int { CASH = 0, CREDIT_CARD = 1, DEBIT_CARD, APP = 3 } table Theater { name:string; address:string; total_capacity:short; mobile:int; base_ticket_price:float; drive_in:bool; payment:PAYMENT_SYSTEM; snacks:[string]; owner: TheaterOwner; } table TheaterOwner { name:string; address:string; } root_type Theater;
现在我们的**Theater**表包含多个属性。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录的**com > tutorialspoint > theater**文件夹中创建一个 Theater、TheaterOwner 和 PAYMENT_SYSTEM 类。我们在应用程序中使用此类,与Flat Buffers - 模式章节中所做的一样。
使用从 fbs 文件创建的 Java 类
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // create offset for name int name = builder.createString("Mery"); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addName(builder, name); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Name: " + theater.name()); System.out.println("Address: " + theater.address()); System.out.println("Total Capacity: " + theater.totalCapacity()); System.out.println("Mobile: " + theater.mobile()); System.out.println("Base Ticket Price: " + theater.baseTicketPrice()); System.out.println("Drive In: " + theater.driveIn()); System.out.println("Snacks: "); if(theater.snacksLength() != 0) { for(int i = 0; i < theater.snacksLength(); i++ ) { System.out.print(" " + theater.snacks(i)); } }else { System.out.println("Snacks are empty."); } System.out.println("Payment Method: " + PAYMENT_SYSTEM.name(theater.payment())); System.out.println("Owner Details: "); TheaterOwner owner = theater.owner(); if(owner != null) { System.out.println("Name: " + owner.name()); System.out.println("Address: " + owner.address()); }else { System.out.println("Owner " + owner); } } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 20
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Name: Mery Address: null Total Capacity: 0 Mobile: 0 Base Ticket Price: 0.0 Drive In: false Snacks: Snacks are empty. Payment Method: CASH Owner Details: Owner null
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为**Theater**对象来读取默认值。
FlatBuffers - JSON 转二进制
概述
JSON 是一种非常流行的网络数据传输格式。为了提供 JSON 兼容性,Flat Buffers 编译器 flatc 可以将源 JSON 转换为 Flat Buffer 二进制格式,然后可以使用该格式反序列化最初由 JSON 表示的对象。
考虑以下包含 Theater 对象信息的 JSON
theater.json
{ "name" : "Silver Screener", "address" : "212, Maple Street, LA, California", "mobile": 12322224 }
theater.fbs
这是我们的 Flat Buffers 模式文件
namespace com.tutorialspoint.theater; table Theater { name:string; address:string; mobile:int; } root_type Theater;
现在让我们首先使用以下命令获取 json(**theater.json**)的 Flat Buffer 二进制表示形式,根据我们的模式(**theater.fbs**):
flatc --binary theater.fbs theater.json
它将在当前文件夹中创建 theater.bin,我们可以读取它来反序列化 Theater 对象。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录的**com > tutorialspoint > theater**文件夹中创建一个 Theater 类。我们在应用程序中使用此类,与Flat Buffers - 模式章节中所做的一样。
使用从 fbs 文件创建的 Java 类
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater.bin"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Name: " + theater.name()); System.out.println("Address: " + theater.address()); System.out.println("Mobile: " + theater.mobile()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater.bin Name: Silver Screener Address: 212, Maple Street, LA, California Mobile: 12322224
因此,正如我们所看到的,我们能够通过将二进制数据反序列化为**Theater**对象来读取默认值。
FlatBuffers - 二进制转 JSON
概述
JSON 是一种非常流行的网络数据传输格式。为了提供 JSON 兼容性,Flat Buffers 编译器 flatc 可以将源 JSON 转换为 Flat Buffer 二进制格式,然后可以使用该格式反序列化最初由 JSON 表示的对象。我们在之前的章节Flat Buffers - JSON 转二进制中已经演练过这个过程。现在我们将执行反向操作,从 Flat Buffers 二进制文件中检索 JSON。
考虑在之前的章节Flat Buffers - JSON 转二进制中创建的 theater.bin 文件。
以下是 Flat Buffers 编译器正确解释二进制数据所需的模式。
theater.fbs
namespace com.tutorialspoint.theater; table Theater { name:string; address:string; mobile:int; } root_type Theater;
生成 JSON
现在让我们首先使用以下命令从我们的二进制文件(**theater.bin**)获取所需的 json(**theater.json**):
flatc --json --raw-binary theater.fbs -- theater.bin
它将在当前文件夹中创建如下所示的 theater.json。
{ name: "Silver Screener", address: "212, Maple Street, LA, California", mobile: 12322224 }
严格模式
flatc 生成最小的 json。如果我们需要使用其他工具处理 JSON 并需要正确的带引号的标识符,则可以使用**--strict-json**,如下所示
flatc --json --raw-binary theater.fbs -- theater.bin --strict-json
它将在当前文件夹中创建如下所示的 theater.json。
{ "name": "Silver Screener", "address": "212, Maple Street, LA, California", "mobile": 12322224 }
默认值
默认情况下,flatc 编译器会忽略默认值,并且默认值不会存储在二进制表示中。因此,这些值也不会出现在 JSON 中。为了实现这一点,我们可以使用**--defaults-json**选项,如下例所示。
让我们将 mobile 值保留为 json 中的默认值。
theater.json
{ "name" : "Silver Screener", "address" : "212, Maple Street, LA, California", "mobile": 0 }
现在让我们首先使用以下命令获取 json(**theater.json**)的 Flat Buffer 二进制表示形式,根据我们的模式(**theater.fbs**):
flatc --binary theater.fbs theater.json
生成不包含默认值的 JSON
现在让我们首先使用以下命令从我们的二进制文件(**theater.bin**)获取所需的 json(**theater.json**):
flatc --json --raw-binary theater.fbs -- theater.bin
它将在当前文件夹中创建如下所示的 theater.json。
{ name: "Silver Screener", address: "212, Maple Street, LA, California" }
生成包含默认值的 JSON
现在使用**--defaults-json**选项生成 JSON。
flatc --json --raw-binary theater.fbs -- theater.bin --defaults-json
它将在当前文件夹中创建如下所示的 theater.json。
{ name: "Silver Screener", address: "212, Maple Street, LA, California", mobile: 0 }
Flat Buffers - 可变缓冲区
概述
每当我们创建一个 Flat Buffers 文件时,从那时起它就是只读的。我们可以使用 flatc 提供的具有常量访问器的类来读取此文件。这有助于在多个读取器中使用 Flat Buffer 文件时保持一致性。但有时,我们可能需要在读取后修改一个值,并需要将修改后的值传递给下一个读取器。我们可以通过从头开始创建一个新的 Flat Buffers 来实现这一点,这对于大型更改来说更好,更高效。对于小型更改,Flat Buffers 提供了一个选项**--gen-mutable**到**flatc**编译器
以生成非常量访问器来修改 FlatBuffers 文件,如下所示flatc --java --gen-mutable theater.fbs
示例
考虑以下模式。
theater.fbs
namespace com.tutorialspoint.theater; table Theater { name:string; address:string; int mobile; } root_type Theater;
从 fbs 文件创建 Java 类
要使用 Flat Buffers,我们现在将使用可变模式下的**flatc**编译器从这个“.fbs”文件创建所需的类。让我们看看如何操作:
flatc --java --gen-mutable theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
首先,让我们创建一个写入器 (writer)来写入theater信息:
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); // create offset for name and address int name = builder.createString("Silver Screener"); int address = builder.createString("212, Maple Street, LA, California"); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add details to the Theater FlatBuffer Theater.addName(builder, name); Theater.addAddress(builder, address); Theater.addMobile(builder, 12233345); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Name: " + theater.name()); System.out.println("Address: " + theater.address()); System.out.println("Mobile: " + theater.mobile()); // Update mobile theater.mutateMobile(22333341); // we can write the theater object again to send it further // read the updated mobile value System.out.println("Updated Mobile: " + theater.mobile()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 76
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Name: Silver Screener Address: 212, Maple Street, LA, California Mobile: 12233345 Updated Mobile: 22333341
FlatBuffers - 语言无关性
概述
到目前为止,我们一直在使用 Java 来序列化和反序列化电影院数据。但是,Google Flat Buffers 提供的一个关键特性是**“语言无关性”**。在本节中,我们将学习如何使用 Java 序列化,并使用 Python 反序列化。
继续我们从Flat Buffers - 字符串章节中的**theater**示例,以下是我们在本例中使用的模式:
theater.fbs
namespace com.tutorialspoint.theater; table Theater { name:string; address:string; } root_type Theater;
使用 Java 序列化
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
首先,让我们创建一个写入器 (writer)来写入theater信息:
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); int name = builder.createString("Silver Screener"); int address = builder.createString("212, Maple Street, LA, California"); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add the name and address to the Theater FlatBuffer Theater.addName(builder, name); Theater.addAddress(builder, address); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 72
使用 Python 反序列化序列化对象
从 proto 文件生成 Python 类
让我们为 Theater 类生成 Python 代码:
flatc --python theater.fbs
执行此命令后,您会在当前目录的**com > tutorialspoint > theater**文件夹中看到一个自动生成的类**Theater.py**。此类将帮助我们反序列化**Theater**对象。
使用生成的 Python 类
现在,让我们**编写**数据读取器,它将使用 Java 读取包含序列化对象的文件:
theaterReader.py
import Theater filename = "E:/theater_flatbuffers_output"; print("Reading from file: " + filename) theater = Theater.Theater() f = open(filename, "rb") buf = f.read() buf = bytearray(buf) theater = theater.GetRootAs(buf); f.close() print("Name: " + theater.Name().decode("utf-8")) print("Address: " + theater.Address().decode("utf-8"))
然后,让我们执行**读取器**。
py theaterReader.py Reading from file: E:/theater_flatbuffers_output Name: Silver Screener Address: 212, Maple Street, LA, California
因此,正如我们所看到的,Java 客户端写入的所有值都被正确地反序列化并由我们的 Python 客户端读取,这有效地意味着 Flat Buffers 是语言无关的。
FlatBuffers - 向后兼容性
概述
FlatBuffers 模式是向后兼容的。这意味着,如果我们稍后更改、添加或删除 FlatBuffers 模式的属性,现有的代码仍然可以工作。这在维护遗留代码库时非常有用。考虑一种情况,其中 Theater 模式仅包含名称和地址,如下所示
theater.fbs
namespace com.tutorialspoint.theater; table Theater { name:string; address:string; } root_type Theater;
如果我们为此模式生成代码,它将支持在 FlatBuffer bin 文件中存储名称和地址。
现在随着时间的推移,我们需要向模式添加一个手机号码,然后我们需要再次生成更新的代码。结果,我们还需要更新写入器和读取器代码。但在生产环境中,通常直接更改代码并不容易,并且进行此类更改可能会破坏整个系统。Flat Buffers 在这里确保旧的读取器代码仍然可以与新的模式生成的 FlatBuffers bin 文件一起正常工作,无需更改。
从 fbs 文件创建 Java 类
要使用 FlatBuffers,我们现在必须使用flatc二进制文件从这个“.fbs”文件创建所需的类。让我们看看如何做到这一点:
flatc --java theater.fbs
这将在当前目录中的com > tutorialspoint > theater文件夹中创建一个 Theater.java 类。我们像在Flat Buffers - Schema章节中所做的那样,在我们的应用程序中使用此类。
使用从 fbs 文件创建的 Java 类
首先,让我们创建一个写入器 (writer)来写入theater信息:
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); int name = builder.createString("Silver Screener"); int address = builder.createString("212, Maple Street, LA, California"); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add the name and address to the Theater FlatBuffer Theater.addName(builder, name); Theater.addAddress(builder, address); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
接下来,我们将有一个读取器 (reader)来读取theater信息:
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Name: " + theater.name()); System.out.println("Address: " + theater.address()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 72
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Name: Silver Screener Address: 212, Maple Street, LA, California
向后兼容性测试
现在让我们向模式添加一个手机号码,更新写入器并运行读取器(无需更新它)以检查向后兼容性。
theater.fbs
namespace com.tutorialspoint.theater; table Theater { name:string; address:string; mobile:int; } root_type Theater;
从 fbs 文件创建 Java 类
使用**flatc**二进制文件从此“.fbs”文件创建所需的类。
flatc --java theater.fbs
使用从 fbs 文件创建的 Java 类
首先,让我们创建一个写入器 (writer)来写入theater信息:
TheaterWriter.java
package com.tutorialspoint.theater; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.google.flatbuffers.FlatBufferBuilder; public class TheaterWriter { public static void main(String[] args) throws FileNotFoundException, IOException { // create a flat buffer builder // it will be used to create Theater FlatBuffer FlatBufferBuilder builder = new FlatBufferBuilder(1024); int name = builder.createString("Silver Screener"); int address = builder.createString("212, Maple Street, LA, California"); // create theater FlatBuffers using startTheater() method Theater.startTheater(builder); // add the name, address and mobile to the Theater FlatBuffer Theater.addName(builder, name); Theater.addAddress(builder, address); Theater.addMobile(builder, 12233345); // mark end of data being entered in Greet FlatBuffer int theater = Theater.endTheater(builder); // finish the builder builder.finish(theater); // get the bytes to be stored byte[] data = builder.sizedByteArray(); String filename = "theater_flatbuffers_output"; System.out.println("Saving theater to file: " + filename); // write the builder content to the file named theater_flatbuffers_output try(FileOutputStream output = new FileOutputStream(filename)){ output.write(data); } System.out.println("Saved theater with following data to disk: \n" + theater); } }
编译项目
现在我们已经设置了**写入器**,让我们编译项目。
mvn clean install
序列化 Java 对象
现在,编译后,让我们先执行写入器:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterWriter Saving theater to file: theater_flatbuffers_output Saved theater with following data to disk: 76
使用旧读取器反序列化序列化对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Name: Silver Screener Address: 212, Maple Street, LA, California
更新读取器并再次反序列化
TheaterReader.java
package com.tutorialspoint.theater; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; public class TheaterReader { public static void main(String[] args) throws FileNotFoundException, IOException { String filename = "theater_flatbuffers_output"; System.out.println("Reading from file " + filename); try(FileInputStream input = new FileInputStream(filename)) { // get the serialized data byte[] data = input.readAllBytes(); ByteBuffer buf = ByteBuffer.wrap(data); // read the root object in serialized data Theater theater = Theater.getRootAsTheater(buf); // print theater values System.out.println("Name: " + theater.name()); System.out.println("Address: " + theater.address()); System.out.println("Mobile: " + theater.mobile()); } } }
编译项目
现在我们已经设置了读取器和写入器,让我们编译项目。
mvn clean install
反序列化已序列化的对象
现在,让我们执行读取器从同一个文件读取:
java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader Reading from file theater_flatbuffers_output Name: Silver Screener Address: 212, Maple Street, LA, California Mobile: 12233345