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,例如JavaPython等。

繼續我們來自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資料夾中建立TheaterPosition類。我們像在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資料夾中建立TheaterPeopleEmployeeViewer類。我們像在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
廣告
© . All rights reserved.