FlatBuffers - 模式



概述

现在让我们使用 Google FlatBuffers 并看看它在一个简单的问候应用程序中如何工作。在这个示例中,我们将创建一个简单的应用程序,它将执行以下操作:

问候语编写器

  • 从用户处获取问候语和用户名

  • 将上述信息存储在磁盘上的文件中

问候语读取器

  • 读取我们在上面存储的文件中的同一个文件

  • 将数据转换为对象并打印数据

FlatBuffers 模式文件

FlatBuffers 的“模式文件”包含我们要序列化的数据的模式定义。数据存储在人类可读的文件中,扩展名为".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从 fa 文件自动生成代码。让我们首先创建一个 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

因此,正如我们看到编写器序列化并保存到文件的数据,该数据被读取器正确地反序列化并相应地打印出来。

广告