- 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