Flat Buffers - Quick Guide



Flat Buffers - Introduction

Before we jump into Flat Buffers, let us go over a brief background of Serialization which is what Flat Buffers does.

What is Serialization and Deserialization?

Whenever we need to persist an object state to memory system, we need serialization. In serialization, we convert the object into bytes and stored the bytes in memory system. These stored bytes can then later be deserialized to get the object state back. As we are converting object to bytes, it can be stored anywhere including file system, messaging queues, databases and so on and then we can transfer these bytes to different machine and retrieve the object state as such.

Why do we need Serialization and Deserialization?

Serialization helps to persist an object state and then we can transfer it to anywhere over the network. Once received, we can deserialized the object or in other words, we can restore our object from bytes on different machine at any time. This is one of the many important use case of Serialization and Deserialization. Another important use case is where object is to be transferred over network. Message Queue, Database objects, REST APIs all work on this principle. In such cases, the object is serialized by the sender first and then transferred to the receiver. Receiver then deserialize the serialized object.

In REST APIs, Micro-services architecture, the application is generally broken down into small services and these services communicate with each other via messaging queue and APIs. As the communication is over network which requires frequent conversion of object to bytes and back to objects. So, serialization and deserialization becomes very critical aspects when it comes to distributed environment.

Why Flat Buffers?

Google Flat Buffers perform the serialization and deserialization of the objects to bytes which can be transferred over the network. But there are some other libraries and mechanisms to transfer data as well.

So, what makes Flat Buffers special? Here are some of its important features −

  • Language independent − Flat Buffers compiler can create code for many languages like Java, Python, Go, C, C++ etc. So, a Java object can be serialized into bytes from a Java program and can be deserialized to a a Python object and vice versa.

  • Efficient Data Compaction − Initially developed for Gaming environment and performance-critical systems, the flat buffers API is designed keeping data compaction and performance in mind. It is very memory efficient and even faster than Google Protocol Buffers, another Google Library for serialization and deserialization.

  • Backward and Forward Compatability − Flat Buffers architecture is both backward and forward compatible. The schema of flat buffers supports adding changes in newer code and allows to deprecated older changes without breaking backward Compatability.

  • Simple to use − Flat Buffers library auto-generate serialization code (as we will see in the upcoming chapters), has a versioning scheme to ensure that the creator of data and the user of data can have separate versions of the serialization definition, etc.

  • JSON convertible Flat buffers schema file can be converted to JSON file and similarly we can convert a JSON file using flat buffers schema.

Flat Buffers vs Others (XML/JSON/Java serialization)

Let's take a look how other ways to transfer data over a network stack up against Flat Buffers.

Feature Flat Buffers JSON XML
Language independent Yes Yes Yes
Serialized data size Least of three Less than XML Highest among the three
Human Readable No, as it uses separate encoding schema Yes, as it uses text based format Yes, as it uses text based format
Serialization speed Fastest among the three Faster than XML Slowest among the three
Data type support Richer than other two. Supports complex data types like Any, one of etc. Supports basic data types Supports basic data types
Support for evolving schema Yes No No

Flat Buffers - Environment Setup

Install Java

We're using Java Based examples to demonstrate Flat Buffers, this section guides you on how to download and set up Java on your machine. Please follow the following steps to set up the environment.

Java SE is freely available from the link Download Java. So you download a version based on your operating system.

Follow the instructions to download java and run the .exe to install Java on your machine. Once you installed Java on your machine, you would need to set environment variables to point to correct installation directories:

Setting up the path for windows 2000/XP:

Assuming you have installed Java in c:\Program Files\java\jdk directory:

  • Right-click on 'My Computer' and select 'Properties'.

  • Click on the 'Environment variables' button under the 'Advanced' tab.

  • Now, alter the 'Path' variable so that it also contains the path to the Java executable. Example, if the path is currently set to 'C:\WINDOWS\SYSTEM32', then change your path to read 'C:\WINDOWS\SYSTEM32;c:\Program Files\java\jdk\bin'.

Setting up the path for windows 95/98/ME:

Assuming you have installed Java in c:\Program Files\java\jdk directory:

  • Edit the 'C:\autoexec.bat' file and add the following line at the end:
    'SET PATH=%PATH%;C:\Program Files\java\jdk\bin'

Setting up the path for Linux, UNIX, Solaris, FreeBSD:

Environment variable PATH should be set to point to where the Java binaries have been installed. Refer to your shell documentation if you have trouble doing this.

Example, if you use bash as your shell, then you would add the following line to the end of your '.bashrc: export PATH=/path/to/java:$PATH'

Popular Java Editors:

To write your Java programs, you will need a text editor. There are even more sophisticated IDEs available in the market. But for now, you can consider one of the following:

  • Notepad: On Windows machine you can use any simple text editor like Notepad (Recommended for this tutorial), TextPad.

  • Netbeans:is a Java IDE that is open-source and free which can be downloaded from https://www.netbeans.org/index.html.

  • Eclipse: is also a Java IDE developed by the eclipse open-source community and can be downloaded from https://www.eclipse.org/.

Install Maven

Maven is project management and build tool. We're using Maven to build our examples. This section guides on how to install and set up maven on your machine. Please follow the following steps to set up the environment.

Maven is freely available from the link Download Maven Installer. So you download a version based on your operating system.

Follow the instructions to download maven zip the extract Maven on your machine. Once you extract Maven files on your machine, you would need to set environment variables to point to correct installation directories. You can follow the instructions at Maven - Environment Setup Chapter.

Install FlatBuffers Library

Once Java and Maven environment is ready. We can use flatbuffers dependency in pom.xml to use it in our java based projects as shown in snippet below −

<dependency>
   <groupId>com.google.flatbuffers</groupId>
   <artifactId>flatbuffers-java</artifactId>
   <version>25.2.10</version>
</dependency>

Build Maven Project

Now when you compile the maven project, maven will automatically download the flatbuffers library, build the code and run accordingly.

mvn clean install

Install FlatBuffer Compiler

Let us install the "flatc" binary which we will use to autogenerate the code from Flat Buffers schema. The binaries can be found at "https://github.com/google/flatbuffers/releases".

Choose the correct binary based on the OS. We will install flat buffers compiler binary on Windows but the steps are not very different for Linux.

We've downloaded https://github.com/google/flatbuffers/releases/download/v25.2.10/Windows.flatc.binary.zip

Verify Flat Buffers Compiler Setup

Once installed, ensure that you are able to access it via command line by adding its path in PATH environment variable −

flatc --version

flatc version 25.2.10

It confirms that Flatc is correctly installed.

Flat Buffers - Schema

Overview

Let us now use Google Flat Buffers and see how it works with a simple Greeting app. In this example, we will create a simple application which would do the following −

Greeting Writer

  • Take greeting and username from the user

  • Store the above information in a file in the disk

Greeting Reader

  • Reads the same file which we stored in the above file

  • Convert that data into an object and print the data

Flat Buffers Schema file

The flat buffers "schema file" contains the schema definition of the data we want to serialize. The data is stored in a human readable file with the extension ".fbs".

Let us store the following data in greeting.fbs and we will use this in our first application.

greeting.fbs

namespace com.tutorialspoint.greeting;

table Greet {
   greeting: string;
   username: string;
}

root_type Greet;

Understanding each construct

namespace com.tutorialspoint.greeting;

The namespace here is used for package/namespace declaration for the generated code from the .fbs file. For example, our generated java classes will be lying in com.tutorialspoint.greeting package.

table Greet

Name of the base class for the object which would be created/recreated.

greeting: string;
username: string;

These are the attributes of the Greet class along with the data type.

root_type Greet;

root_type tells the flat buffers compiler about the root table which is Greet and will be the main class while generating code.

Flat Buffers Code Generation

Now that we have defined, let us install the "flatc" binary which we will use to autogenerate the code for the above Greet class. The binaries can be found at "https://github.com/google/flatbuffers/releases".

Choose the correct binary based on the OS. We will install flat buffers compiler binary on Windows but the steps are not very different for Linux.

We've downloaded https://github.com/google/flatbuffers/releases/download/v25.2.10/Windows.flatc.binary.zip

Verify Flat Buffers Compiler Setup

Once installed, ensure that you are able to access it via command line −

flatc --version

flatc version 25.2.10

It confirms that Flatc is correctly installed. Now let us move to creating the Greeting app described above for Java.

Greeting App in Java

Now that we have installed flatc, we can auto-generate the code from the fa files using flatc. Let us first create a Java project though.

Following is the Maven configuration that we will use for our Java project. Note that it contains the required library for flatc-java as well.

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>25.2.10</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>

All of our code would be present under src/main/java.

With the project structure out of the way, let us generate the code for the Greet class −

Generate Java Classes

flatc --java greeting.fbs

Post execution of the command, you will notice a auto-generated class under com > tutorialspoint > greeting folder within current directory.

  • Greet.java

This file contains a class Greet which would help us with serialization and deserialization of the Greet object.

Using Generated Java Classes

Now, let us write the writer of the data, which will take the username and the greeting as its inputs −

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);
   }   
}

The writer simply takes CLI arguments, creates the Greet object, serializes it and then dumps it to a file.

Now let us write a reader which will read the file −

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());
      }
   }
}

The reader simply reads from the same file, deserializes it, and prints the data about the greeting.

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

And now, let us first execute the writer to serialize an object to file system.

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

Deserialize the Serialized Object

And then, let us execute the reader to deserialize an object from file system.

java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.greeting.GreetReader

Reading from file greeting_protobuf_output
Greeting: Hello
Username: John

So, as we see the data that was serialized by the writer and saved to the file, that exact data is correctly deserialized by the reader and printed accordingly.

Flat Buffers - Constructs

Overview

Let us now look at a few basic data structures and data types which Google Flat Buffers provides. We will look at these data structures using an example of a Movie theater.

Note that for this structure while we will be using Java code, using them in Python code should also be equally simple and possible.

In the next few chapters, we will discuss the following Flat Buffers data types one by one −

Data Types

  • table − "table" is a very basic building block of Flat Buffers. This translates to a class in the languages that we use, for example, Java, Python, etc

  • string − "string" data type translate to a string in the languages that we use, for example, Java, Python, etc

  • Numbers − Numbers include Flat Buffers types like int, short, float, double, which are basic building blocks of Protobuf. It translates to int, long float, double, respectively, in the languages that we use, for example, Java, Python, etc. We can use alias as well like int16 for short, float32 for float etc.

  • bool − "bool" data type is one of the basic building blocks of Flat Buffers. It translates to Boolean in the languages that we use, for example, Java, Python, etc.

  • enum − "enum" is one of the composite datatypes of Flat Buffers. It translates to an enum in the languages that we use, for example, Java.

  • vector − [] notation is used to create vector or array and is one of the composite datatypes of Flat Buffers. Flat Buffers vector is similar to java array.

  • struct − "struct" is one of the composite datatypes of Flat Buffers. It is used to create non-modifiable set of scalar values. struct uses less memory and is very fast in lookup.

  • Nested Class − We can use an class created using "table" within another "table" and thus creating a nested class.

  • union − "union" is used to create a structure which can accept any of the different type of values.

Flat Buffers - Table

Overview

The very basic building block of Flat Buffers is the table attribute. This is equivalent to a class in the languages that we use, for example, Java, Python, etc.

Example Code

Following is the syntax that we need to have to instruct Flat Buffers that we will be creating instances of a given table −

namespace com.tutorialspoint.theater;

table Theater {
}
root_type Theater;

We will save the above in "theater.fbs" and we will use this when we explore other data structures.

Explanation

namespace com.tutorialspoint.theater;

This argument is specific to Java, i.e., the package where the code from the ".fbs" file will be auto-generated. The class Theater will be created in com.tutorialpoint.theater package.

Next, we're creating a table, Theater −

table Theater

This is nothing but the class name of the base class for the object which would be created/recreated. Note that it is useless in its current shape, as it does not have any other attributes. But we will be more adding attributes as we move along.

Using multiple table attributes

A single fbs file can also have multiple tables. For example, if we want, we can add a Visitor table as well in the same file. Flat Buffers would ensure that Theater class remains main class using root_type attribute. For example −

namespace com.tutorialspoint.theater;

table Theater {
}

table Visitor {
}
root_type Theater;

Creating Java Classes from fbs file

To use Flat Buffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc --java theater.fbs

Using Java Classes created from a fbs file

Well, that is it! The above command should create the required files in the current directory and now we can use them in our Java code −

// Create a FlatBuffer Builder with default buffer
FlatBufferBuilder builder = new FlatBufferBuilder(1024);

// Create Theater FlatBuffers using startTheater() method
Theater.startTheater(builder);

At this stage, it is not very useful, as we have not added any attributes to the table. Let us do that when we look at strings in Flat Buffers - string chapter.

Flat Buffers - Numbers

Overview

Numbers include flatbuffers types like int, short, float, double which are basic building blocks of Flat Buffers. It translates to int, short float, double, respectively, in the languages that we use, for example, Java, Python, etc.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct Flat Buffers that we will be creating numbers

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   total_capcity:int;
   mobile:long;
   base_ticket_price:float;
}
root_type Theater;

Now our table contains numerical attributes. Default value is 0 or 0.0 as applicable.

Creating Java Classes from FBS File

To use Flat Buffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create a Theater.java class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

First let's create a writer to write the theater information −

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);
   }
}	

Next, we will have a reader to read the theater information −

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());
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

So, as we see, we are able to read the serialized strings by deserializing the binary data to the Theater object. Let us now look at numbers in the next chapter Flat Buffers - bool .

Flat Buffers - Boolean

Overview

The bool data type is one of the basic building blocks of Flat Buffers. It translates to Boolean in the languages that we use, for example, Java, Python, etc.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct Flat Buffers that we will be creating bool

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   drive_in:bool;
}
root_type Theater;

Now our table contains a bool attribute. Default value is false.

Creating Java Classes from FBS File

To use Flat Buffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create a Theater.java class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

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);
   }
}	

Next, we will have a reader to read the theater information −

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());
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader

Reading from file theater_flatbuffers_output
Drive In: true

So, as we see, we are able to read the serialized strings by deserializing the binary data to the Theater object. Let us now look at numbers in the next chapter Flat Buffers - Enum .

Flat Buffers - enum

Overview

The enum data type is one of the composite datatypes of Flat Buffers. It is equivalent to an enum in the languages that we use, for example, Java etc.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct FlatBuffers that we will be creating an 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;

Now our table contains an enum attribute. We've assigned a value to each enum constant except one DEBIT_CARD which by default take the incremental value as 2.

We define the enum and use it below as the data type along with "payment" attribute.

Creating Java Classes from fbs File

To use FlatBuffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create a Theater.java and PAYMENT_SYSTEM class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

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);
   }
}	

Next, we will have a reader to read the theater information −

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());
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

> 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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader

Reading from file theater_flatbuffers_output
Payment Method: 2

So, as we see, we are able to read the serialized enum by deserializing the binary data to Theater object. In the next chapter Protocol Buffers - Vector, we will look at the vector, a composite type.

Flat Buffers - Vector

Overview

The Vector data type is one of the composite datatypes of Flat Buffers. It is equivalent to an array or List in the languages that we use, for example, Java etc.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct FlatBuffers that we will be creating a vector

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   snacks:[string];  // vector of strings
   tickets:[float];    // vector of floats 	
}
root_type Theater;

Now our table contains vector attributes of string and float.

Creating Java Classes from fbs File

To use FlatBuffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create a Theater.java class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

Creating and Writing Vector

In order to create a Vector, we need to first prepare the offset of scalar type array and then we can add the vector to the 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);

Following example code is showing the process of creating a Vector of String and ints.

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);
   }
}	

Reading Vector

In order to read a Vector, we have methods to get the length of vector and to get an entry by an index as shown below.

// 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));
}

Following example code is showing the process of reading a Vector of String and ints.

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));
         }         
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

> 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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

So, as we see, we are able to read the serialized vector by deserializing the binary data to Theater object. In the next chapter Flat Buffers - struct, we will look at the sector, a composite type.

Flat Buffers - struct

Overview

The struct data type is one of the composite datatypes of Flat Buffers. It is used to create a immutable data structure. A struct takes less memory is quite fast in lookup. A struct is generally a combination of scalar types.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct FlatBuffers that we will be creating a struct

theater.fbs

namespace com.tutorialspoint.theater;

struct Position {
   x: int;
   y: int;
   z: int;
}
table Theater {
   location: Position;
}
root_type Theater;

Now our table contains struct attribute defined as location of type Position. Position is a struct to define a data structure of three ints.

Creating Java Classes from fbs File

To use FlatBuffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create Theater and Position classes in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

Creating and Writing Struct

In order to create a Struct, we need to first prepare the offset of scalar type array and then we can add the vector to the 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); 

Following example code is showing the process of creating a Struct of Ints.

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);
   }
}	

Reading Struct

In order to read a Struct, we have methods to get each value of struct.

Position position = theater.location();
System.out.println("x: " + position.x());
System.out.println("y: " + position.y());
System.out.println("z: " + position.z());

Following example code is showing the process of reading a Struct of int.

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());        
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

> 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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

So, as we see, we are able to read the serialized struct by deserializing the binary data to Theater object. In the next chapter Flat Buffers - union, we will look at the union, a composite type.

Flat Buffers - union

Overview

The union data type is one of the composite datatypes of Flat Buffers. It is used to create a flexible data struture which can take any of the required type.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct FlatBuffers that we will be creating a 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;

Now our table contains union attribute defined as People of two tables Employee and Viewer. In Theater table, we've defined people of our union type which means which we can store any of the Employee or Viewer in people variable.

Creating Java Classes from fbs File

To use FlatBuffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create Theater, People, Employee and Viewer classes in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

Creating and Writing Union

In order to create a Union, we need to first prepare the offset of required type, for example Viewer and then we can add the viewer along with its type to the 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);

Following example code is showing the process of creating a Union.

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);
   }
}	

Reading Union

In order to read a Union, we can check the type of the union object and then retrieve values accordingly..

// 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()); 
}

Following example code is showing the process of reading a Union.

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()); 
         }       
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

> 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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

java -cp .\target\flatbuffers-tutorial-1.0.jar com.tutorialspoint.theater.TheaterReader

Reading from file theater_flatbuffers_output
People:
Name: Mery
Address: Avenue 4

So, as we see, we are able to read the serialized struct by deserializing the binary data to Theater object. In the next chapter Flat Buffers - Nested Tables, we will look at the Nested Tables, a composite type.

Flat Buffers - Nested Table

Overview

Here, we will see how to create a nested table in Flat Buffers. It is equivalent to a nested Java class.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct FlatBuffers that we will be creating a nested table

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   owner: TheaterOwner;
}

table TheaterOwner {
	name:string;
	address:string;
}
root_type Theater;

Now our Theater table contains a nested table, i.e., information about the owner of the theater.

Creating Java Classes from fbs File

To use FlatBuffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc --java theater.fbs

This will create a Theater and TheaterOwner classes in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

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);
   }
}	

Next, we will have a reader to read the theater information −

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());        
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

So, as we see, we are able to read the serialized nested table/object by deserializing the binary data to the Theater object.

Flat Buffers - Default Values

Overview

We've seen in our previous examples, how to serialize and deserialize various types in flat buffers. In case, we do not specify any value then a default value is stored. If we've specify the same default value for the variable, then no extra space is allocated by flatbuffers.

Flat Buffers supports default values of its data types as per given table below −

Data Type Default value
int16 / short / int / long 0
Float/double 0.0
String Empty string
Boolean False
Enum First Enum item, that is the one with "index=0"
Vector Empty list
Nested Class null

So, if one does not specify the data for these data types, then they would take the above default values. Now, let's continue with our theater example to demonstrate how it works.

In this example, we will let all the fields default. The only field which would be specified would be the name of the theater.

Continuing with our theater example from Flat Buffers - String chapter, following is the syntax that we need to have to instruct FlatBuffers that we will be creating various data types −

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;

Now our Theater table contains multiple attributes.

Creating Java Classes from fbs File

To use FlatBuffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc --java theater.fbs

This will create a Theater, TheaterOwner and PAYMENT_SYSTEM classes in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

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);
   }
}	

Next, we will have a reader to read the theater information −

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);
         }        
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

So, as we see, we are able to read the default values by deserializing the binary data to the Theater object.

Flat Buffers - JSON to Binary

Overview

JSON is very popular data transfer format over the network. In order to provide JSON compatability, Flat Buffers complier flatc has option to convert a source JSON to flat buffer binary format which can then be used to deserialize objects represented originally by JSON.

Consider the following JSON carrying a Theater object information

theater.json

{
   "name" : "Silver Screener",
   "address" : "212, Maple Street, LA, California",
   "mobile": 12322224
}

theater.fbs

This is our Flat Buffers Schema file

namespace com.tutorialspoint.theater;

table Theater {
   name:string;
   address:string;
   mobile:int;
}
root_type Theater;

Now let's first get the flat buffer binary representation of json (theater.json) as per our schema (theater.fbs) using below command.

flatc --binary theater.fbs theater.json

It will create theater.bin in the current folder which we can read to deserialize the Theater object.

Creating Java Classes from fbs File

To use FlatBuffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create a Theater class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Class created from fbs File

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());        
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

So, as we see, we are able to read the default values by deserializing the binary data to the Theater object.

Flat Buffers - Binary to JSON

Overview

JSON is very popular data transfer format over the network. In order to provide JSON compatability, Flat Buffers complier flatc has option to convert a source JSON to flat buffer binary format which can then be used to deserialize objects represented originally by JSON. This we've exercised in our previous chapter Flat Buffers - JSON to Binary. Now we'll perform the reversal where we'll retrive the JSON from Flat Buffers Binary file.

Consider the theater.bin file created in previous chapter Flat Buffers - JSON to Binary.

Following is the our schema which is required for flat buffers compiler to correctly interpret the binary data.

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   name:string;
   address:string;
   mobile:int;
}
root_type Theater;

Generate JSON

Now let's first get the required json (theater.json) from our binary (theater.bin) using below command.

flatc --json --raw-binary theater.fbs -- theater.bin

It will create theater.json in the current folder as follows.

{
   name: "Silver Screener",
   address: "212, Maple Street, LA, California",
   mobile: 12322224
}

Strict Mode

flatc generates minimal json. In case, we need to process JSON with other tools and proper quoted identifiers are required then we can use --strict-json as shown below:

flatc --json --raw-binary theater.fbs -- theater.bin --strict-json

It will create theater.json in the current folder as follows.

{
   "name": "Silver Screener",
   "address": "212, Maple Street, LA, California",
   "mobile": 12322224
}

Default Values

By default, flatc compiler ignores default values and default values are not stored in binary representation. Thus those values will not come in JSON as well. In order to achieve this, we can use --defaults-json option as shown in below example.

Let's keep mobile value as default in json.

theater.json

{
   "name" : "Silver Screener",
   "address" : "212, Maple Street, LA, California",
   "mobile": 0
}

Now let's first get the flat buffer binary representation of json (theater.json) as per our schema (theater.fbs) using below command.

flatc --binary theater.fbs theater.json

Generate JSON without default

Now let's first get the required json (theater.json) from our binary (theater.bin) using below command.

flatc --json --raw-binary theater.fbs -- theater.bin

It will create theater.json in the current folder as follows.

{
   name: "Silver Screener",
   address: "212, Maple Street, LA, California"
}

Generate JSON with default

Now generate the JSON with --defaults-json option.

flatc --json --raw-binary theater.fbs -- theater.bin --defaults-json

It will create theater.json in the current folder as follows.

{
   name: "Silver Screener",
   address: "212, Maple Street, LA, California",
   mobile: 0
}

Flat Buffers - Mutable Buffers

Overview

Whenever we create a Flat Buffers file, it is readonly from there on. We can read this file using the classes provided by flatc which has const accessors. This helps to keep consisting in using flat buffer file across multiple readers. But sometime, we may need to modify a value after reading and require to pass on modified value to next reader. We can achieve it by creating a new flat buffers from scrach which is better and efficient for large changes. In case of small change, Flat Buffers provides a option --gen-mutable to flatc complier

to generate non-const accessors to modify the flatbuffers file as shown below:
flatc --java --gen-mutable theater.fbs

Example

Consider the following schema.

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   name:string;
   address:string;
   int mobile;
}
root_type Theater;

Creating Java Classes from fbs File

To use Flat Buffers, we will now using flatc compiler in mutable mode to create the required class from this ".fbs" file. Let us see how to do that −

flatc  --java --gen-mutable theater.fbs

This will create a Theater.java class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

First let's create a writer to write the theater information −

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);
   }
}	

Next, we will have a reader to read the theater information −

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());
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

Flat Buffers - Language Independence

Overview

Till now, we have been using Java to serialize and deserialize the Movie Theater data. However, one of the key features that Google Flat buffers provides is "language independence". In this chapter, we will see how to serialize using Java and deserialize using Python.

Continuing with our theater example from Flat Buffers - String chapter, following is the schema that we are using in this example −

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   name:string;
   address:string;
}
root_type Theater;

Serialization using Java

To use Flat Buffers, we will now have to use flatc binary to create the required classes from this ".fbs" file. Let us see how to do that −

flatc --java theater.fbs

This will create a Theater.java class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

First let's create a writer to write the theater information −

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);
   }
}	

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object Using Python

Generate Python classes from proto file

Let us generate the python code for Theater class −

flatc  --python theater.fbs

Post execution of this command, you will notice an auto-generated class Theater.py in com > tutorialspoint > theater folder in current directory. This class would help us with deserialization of the Theater object.

Using Generated Python Classes

Now, let us write the reader of the data, which will read the file containing serialized object using 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"))

And then, let us execute the reader.

py theaterReader.py

Reading from file: E:/theater_flatbuffers_output
Name: Silver Screener
Address: 212, Maple Street, LA, California

So, as we see, all the values which were written by the Java client were correctly deserialized and read by our Python client which effectively means Flat Buffers is language independent.

Flat Buffers - Backward Compatability

Overview

FlatBuffers schema is backward compatible. It means, if we change add or remove attributes to a flatbuffers schema later, still the existing code can work. This is very useful while maintaining the legacy codebase. Consider a scenario where Theater Schema contains only name and address as shown below:

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   name:string;
   address:string;
}
root_type Theater;

If we generate code for this schema, it will support storing name and address in flatbuffer bin file.

Now with time, we need to add a mobile number to the schema, then we need to generate the updated code again. And as a consequence, we need to updated writer and reader code as well. But in production, generally changing code directly is not easy and making such a change may break the entire system. Flat buffers here ensure that old reader code will still working fine with the new schema based generated flatbuffers bin file with no change.

Creating Java Classes from fbs File

To use Flat Buffers, we will now have to use flatc binary to create the required class from this ".fbs" file. Let us see how to do that −

flatc  --java theater.fbs

This will create a Theater.java class in com > tutorialspoint > theater folder in current directory. We're using this class in our application similar to as done in Flat Buffers - Schema chapter.

Using Java Classes created from fbs File

First let's create a writer to write the theater information −

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);
   }
}	

Next, we will have a reader to read the theater information −

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());
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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

Backward Compatability Test

Now let's add a mobile number to the schema, update the writer and run the reader without updating it to check the backward compatability.

theater.fbs

namespace com.tutorialspoint.theater;

table Theater {
   name:string;
   address:string;
   mobile:int;
}
root_type Theater;

Creating Java Classes from fbs File

Use flatc binary to create the required class from this ".fbs" file.

flatc  --java theater.fbs

Using Java Classes created from fbs File

First let's create a writer to write the theater information −

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);
   }
}	

Compile the project

Now that we have set up the writer, let us compile the project.

mvn clean install

Serialize the Java Object

Now, post compilation, let us execute the writer first −

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

Deserialize the Serialized Object Using old reader

Now, let us execute the reader to read from the same file −

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

Update Reader and Deserialize again

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());
      }
   }
}

Compile the project

Now that we have set up the reader and the writer, let us compile the project.

mvn clean install

Deserialize the Serialized Object

Now, let us execute the reader to read from the same file −

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
Advertisements