- FlatBuffers 教程
- FlatBuffers - 首页
- FlatBuffers - 简介
- FlatBuffers - 模式
- FlatBuffers - 构造
- FlatBuffers - 表
- FlatBuffers - 字符串
- FlatBuffers - 数字
- FlatBuffers - 布尔值
- FlatBuffers - 枚举
- FlatBuffers - 向量
- FlatBuffers - 结构体
- FlatBuffers - 联合体
- FlatBuffers - 嵌套表
- FlatBuffers - 默认值
- FlatBuffers - JSON 转二进制
- FlatBuffers - 二进制转 JSON
- FlatBuffers - 可变缓冲区
- FlatBuffers - 向后兼容性
- FlatBuffers - 语言无关性
- FlatBuffers 有用资源
- FlatBuffers - 快速指南
- FlatBuffers - 有用资源
- FlatBuffers - 讨论
FlatBuffers - 联合体
概述
联合体数据类型是 FlatBuffers 的复合数据类型之一。它用于创建灵活的数据结构,可以采用任何所需类型。
继续我们从Flat Buffers - 字符串章节的剧院示例,以下是我们需要用来指示 FlatBuffers 将要创建一个联合体的语法:
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 - 模式章节中所做的一样。
使用从 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);
}
}
读取联合体
为了读取联合体,我们可以检查联合体对象的类型,然后相应地检索值。
// 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 对象
现在,编译后,让我们先执行写入器:
> 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对象来读取序列化的结构体。在下一章Flat Buffers - 嵌套表中,我们将了解复合类型的嵌套表。
广告