Java中使用FlatBuffers實現序列化

banq發表於2024-05-07

Java 中的 FlatBuffers有助於高速資料序列化/反序列化,消除解析開銷。它由 Google 開發,為跨平臺資料交換提供無模式、記憶體高效的解決方案。 Java 開發人員可以利用其直接記憶體訪問來實現最佳效能和最小記憶體佔用,從而提高應用程式速度、可擴充套件性和互操作性。讓我們深入瞭解 Java FlatBuffers 序列化。

什麼是Java中的序列化和FlatBuffers?
在Java程式設計中,序列化是指將物件轉換為位元組流的過程。然後可以將該位元組流儲存在檔案中、透過網路傳送或儲存在資料庫中。序列化對於不同系統之間的資料永續性和通訊至關重要。

Java 中的序列化
Java 透過 Serialized 介面提供了對序列化的內建支援。實現此介面的類可以使用 Java 的 ObjectOutputStream 和 ObjectInputStream 類進行序列化和反序列化。此外,Java 還提供了一個可外部化的介面,用於對序列化過程進行更細粒度的控制。

Java 中的 FlatBuffer
FlatBuffers是Google開發的一個高效的跨平臺序列化庫。與傳統的序列化方法不同,FlatBuffers 不需要解析。相反,它們提供對序列化資料的直接訪問,從而加快序列化和反序列化速度。在 Java 中,FlatBuffers 是透過程式碼生成器實現的,該程式碼生成器根據模式定義生成 Java 類。這些生成的類使開發人員能夠輕鬆地序列化和反序列化資料,而無需手動解析或反射。這樣可以以最小的開銷實現高效能的資料處理。

使用 FlatBuffers 的好處

  • 高效的記憶體使用:與其他序列化格式相比,FlatBuffers 使用記憶體的效率更高。
  • 高速序列化和反序列化:直接訪問序列化資料可以加快處理速度。
  • 支援架構演變:FlatBuffers 允許架構更改,而不會破壞向後相容性。
  • 平臺獨立性:序列化資料可以在不同平臺和程式語言之間共享。

程式碼演示:
依賴:

<!-- https:<font>//mvnrepository.com/artifact/com.google.flatbuffers/flatbuffers-java --><i>
<dependency>
    <groupId>com.google.flatbuffers</groupId>
    <artifactId>flatbuffers-java</artifactId>
    <version>24.3.25</version>
</dependency>

FlatBuffers 結構schema檔案 (.fbs)
在 FlatBuffers 中,資料結構是使用副檔名為.fbs.該檔案指定資料結構的佈局,包括其欄位及其型別。讓我們看一下定義人員物件的示例模式檔案:

<font>// Define schema in a .fbs file<i>
table Person {
    name: string;
    age: int;
    hobbies: [string];
}

在此schema中,我們定義一個名為“Person”的表,其中包含三個欄位:字串型別的“name”、int 型別的“age”和字串陣列的“hobbies”。該模式充當生成程式碼的藍圖,以便在序列化和反序列化過程中使用定義的資料結構。

使用 FlatBuffers
一旦定義了結構schema,我們就可以使用 FlatBuffers 程式碼生成器來生成與該結構schema相對應的 Java 類。

  • 這些生成的類提供了建立、訪問和操作已定義資料結構例項的方法。
  • 該類Person將由 FlatBuffer 編譯器 ( ) 根據提供的結構schema生成flatc,並將包含操作已定義資料結構所需的類和方法。

值得慶幸的是,所有這些都是由 IDE 自動完成的,因為我們已經在專案中包含了必要的依賴項。

<font>// Java code to serialize and deserialize<i>
package com.jcg.example;

import com.google.flatbuffers.FlatBufferBuilder;
import com.example.Person;

public class Main {
    public static void main(String[] args) {
       
// Create FlatBufferBuilder<i>
        FlatBufferBuilder builder = new FlatBufferBuilder();

       
// Create hobbies strings<i>
        int[] hobbies = {
            builder.createString(
"Reading"),
            builder.createString(
"Gaming")
        };

       
// Serialize person object<i>
        int personOffset = Person.createPerson(builder, builder.createString(
"John"), 30, Person.createHobbiesVector(builder, hobbies));
        builder.finish(personOffset);

       
// Deserialize person object<i>
        byte[] buf = builder.sizedByteArray();
        ByteBuffer bb = ByteBuffer.wrap(buf);
        Person person = Person.getRootAsPerson(bb);

       
// Access deserialized data<i>
        System.out.println(
"Name: " + person.name());
        System.out.println(
"Age: " + person.age());
        for (int i = 0; i < person.hobbiesLength(); i++) {
            System.out.println(
"Hobby " + (i+1) + ": " + person.hobbies(i));
        }
    }
}

在此程式碼中,我們使用 FlatBufferBuilder 建立一個 FlatBuffer 例項,表示一個名為““John”, age 30, 愛好hobby是 “Reading” 和“Gaming”的Person人員物件。然後,我們序列化該物件,將其反序列化回來,並訪問反序列化的資料進行列印。

程式碼輸出
程式碼輸出顯示了使用 FlatBuffers 在 Java 中對人物件進行序列化和反序列化後的反序列化資料。

Name: John
Age: 30
Hobby 1: Reading
Hobby 2: Gaming

使用 FlatBuffers 進行 JSON 轉換
將 FlatBuffers 資料轉換為 JSON 格式非常簡單。 FlatBuffers 提供了直接將 FlatBuffers 物件序列化為 JSON 字串的方法。這些方法根據模式定義自動生成資料的 JSON 表示形式,從而可以輕鬆地在 FlatBuffers 應用程式中使用 JSON 資料。

考慮一個簡單的例子,我們有一個包含姓名、年齡和愛好等欄位的人的模式。我們可以在檔案中定義此模式.fbs並使用 FlatBuffers 程式碼生成工具生成 Java 類。然後,我們可以使用生成的程式碼將 JSON 資料解析為 FlatBuffers 物件,反之亦然。

import com.google.flatbuffers.FlatBufferBuilder;
import com.google.flatbuffers.FlexBuffers;

public class Main {
    public static void main(String[] args) {
        <font>// Define schema for a person<i>
        String schema =
"table Person { name:string; age:int; hobbies:[string]; }";
        
       
// Create FlatBufferBuilder<i>
        FlatBufferBuilder builder = new FlatBufferBuilder();
        
       
// Start building FlatBuffer<i>
        int nameOffset = builder.createString(
"John");
        int[] hobbiesOffsets = { builder.createString(
"Reading"), builder.createString("Gaming") };
        int hobbiesVector = Person.createHobbiesVector(builder, hobbiesOffsets);
        Person.startPerson(builder);
        Person.addName(builder, nameOffset);
        Person.addAge(builder, 30);
        Person.addHobbies(builder, hobbiesVector);
        int personOffset = Person.endPerson(builder);
        Person.finishPersonBuffer(builder, personOffset);

       
// Serialize FlatBuffer to JSON<i>
        byte[] flatBufferBytes = builder.sizedByteArray();
        FlexBuffers.TypedBuffer buffer = FlexBuffers.getRoot(new FlexBuffers.ByteBufferWrapper(flatBufferBytes));
        String json = buffer.toJson(schema);

       
// Print JSON representation<i>
        System.out.println(
"JSON representation:");
        System.out.println(json);

       
// Deserialize JSON to FlatBuffer<i>
        FlexBuffers.Builder flexBuilder = new FlexBuffers.Builder();
        flexBuilder.fromJson(json, schema);
        FlexBuffers.TypedBuffer typedBuffer = flexBuilder.finish();
        byte[] flatBufferFromJson = typedBuffer.toByteArray();

       
// Access FlatBuffer data<i>
        ByteBuffer byteBuffer = ByteBuffer.wrap(flatBufferFromJson);
        Person person = Person.getRootAsPerson(byteBuffer);
        System.out.println(
"\nDeserialized data:");
        System.out.println(
"Name: " + person.name());
        System.out.println(
"Age: " + person.age());
        System.out.println(
"Hobbies:");
        for (int i = 0; i < person.hobbiesLength(); i++) {
            System.out.println(
"- " + person.hobbies(i));
        }
    }
}

在此示例中,我們為一個人定義一個schema結構,其中包含姓名、年齡和愛好等欄位。然後,我們建立一個 FlatBuffer 來表示具有一些示例資料的人員物件。我們使用 FlexBuffers 將此 FlatBuffer 序列化為 JSON 格式。之後,我們將 JSON 反序列化回 FlatBuffer 並訪問資料。

上述程式碼的輸出將是:

JSON representation:
{
  <font>"name": "John",
 
"age": 30,
 
"hobbies": ["Reading", "Gaming"]
}

Deserialized data:
Name: John
Age: 30
Hobbies:
- Reading
- Gaming

結論
使用 FlatBuffers 就像擁有在計算機程式中儲存和組織資料的超能力。首先描述資料在稱為模式的特殊檔案中的外觀。然後,您使用工具根據該架構生成程式碼。此程式碼可幫助您輕鬆快速地管理資料,而不會犧牲速度。

FlatBuffers 很棒,因為它可以讓您直接以緊湊的序列化形式訪問資料,從而使其快速高效。另外,它很靈活——即使您稍後更改資料結構,FlatBuffers 也可以順利處理。

FlatBuffers 的一個很酷的事情是它可以輕鬆地在自己的格式和 JSON 之間轉換資料,JSON 是一種常見的資料表示方式。這意味著您可以使用 FlatBuffers 來處理 JSON 資料,而不會減慢程式速度。

總體而言,FlatBuffers 使程式中的資料處理變得簡單。無論您是儲存資訊還是在不同系統之間共享資訊,FlatBuffers 都能以其易於使用的工具和快速的效能滿足您的需求。
​​​​​​​

相關文章