
- Flat Buffers - Home
- Flat Buffers - Introduction
- Flat Buffers - Environment Setup
- Flat Buffers - Schema
- Flat Buffers - Constructs
- Flat Buffers - table
- Flat Buffers - string
- Flat Buffers - Numbers
- Flat Buffers - Boolean
- Flat Buffers - Enum
- Flat Buffers - Vector
- Flat Buffers - Struct
- Flat Buffers - Union
- Flat Buffers - Nested Table
- Flat Buffers - Default Values
- Flat Buffers - JSON to Binary
- Flat Buffers - Binary to JSON
- Flat Buffers - Mutatable Buffers
- Flat Buffers - Backward Compatability
- Flat Buffers - Language Independence
- Flat Buffers Useful Resources
- Flat Buffers - Quick Guide
- Flat Buffers - Useful Resources
- Flat Buffers - Discussion
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 FileFirst 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