Use in Java/C#    {#flatbuffers_guide_use_java_c-sharp}
==============

## Before you get started

Before diving into the FlatBuffers usage in Java or C#, it should be noted that
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
general FlatBuffers usage in all of the supported languages (including both Java
and C#). This page is designed to cover the nuances of FlatBuffers usage,
specific to Java and C#.

You should also have read the [Building](@ref flatbuffers_guide_building)
documentation to build `flatc` and should be familiar with
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
[Writing a schema](@ref flatbuffers_guide_writing_schema).

## FlatBuffers Java and C-sharp code location

#### Java

The code for the FlatBuffers Java library can be found at
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
java/com/google/flatbuffers).

#### C-sharp

The code for the FlatBuffers C# library can be found at
`flatbuffers/net/FlatBuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
FlatBuffers).

## Testing the FlatBuffers Java and C-sharp libraries

The code to test the libraries can be found at `flatbuffers/tests`.

#### Java

The test code for Java is located in [JavaTest.java](https://github.com/google
/flatbuffers/blob/master/tests/JavaTest.java).

To run the tests, use either [JavaTest.sh](https://github.com/google/
flatbuffers/blob/master/tests/JavaTest.sh) or [JavaTest.bat](https://github.com/
google/flatbuffers/blob/master/tests/JavaTest.bat), depending on your operating
system.

*Note: These scripts require that [Java](https://www.oracle.com/java/index.html)
is installed.*

#### C-sharp

The test code for C# is located in the [FlatBuffers.Test](https://github.com/
google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
https://www.visualstudio.com), and compile/run the project.

Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
Once you have installed `Mono`, you can run the tests from the command line
by running the following commands from inside the `FlatBuffers.Test` folder:

~~~{.sh}
  mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
  mono Assert.exe
~~~

## Using the FlatBuffers Java (and C#) library

*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
example of how to use FlatBuffers in Java or C#.*

FlatBuffers supports reading and writing binary FlatBuffers in Java and C#.

To use FlatBuffers in your own code, first generate Java classes from your
schema with the `--java` option to `flatc`. (Or for C# with `--csharp`).
Then you can include both FlatBuffers and the generated code to read
or write a FlatBuffer.

For example, here is how you would read a FlatBuffer binary file in Java:
First, import the library and generated code. Then, you read a FlatBuffer binary
file into a `byte[]`.  You then turn the `byte[]` into a `ByteBuffer`, which you
pass to the `getRootAsMyRootType` function:

*Note: The code here is written from the perspective of Java. Code for both
languages is both generated and used in nearly the exact same way, with only
minor differences. These differences are
[explained in a section below](#differences_in_c-sharp).*

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
    import MyGame.Example.*;
    import com.google.flatbuffers.FlatBufferBuilder;

    // This snippet ignores exceptions for brevity.
    File file = new File("monsterdata_test.mon");
    RandomAccessFile f = new RandomAccessFile(file, "r");
    byte[] data = new byte[(int)f.length()];
    f.readFully(data);
    f.close();

    ByteBuffer bb = ByteBuffer.wrap(data);
    Monster monster = Monster.getRootAsMonster(bb);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Now you can access the data from the `Monster monster`:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
    short hp = monster.hp();
    Vec3 pos = monster.pos();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

<a name="differences_in_c-sharp">
#### Differences in C-sharp
</a>

C# code works almost identically to Java, with only a few minor differences.
You can see an example of C# code in
`tests/FlatBuffers.Test/FlatBuffersExampleTests.cs` or
`samples/SampleBinary.cs`.

First of all, naming follows standard C# style with `PascalCasing` identifiers,
e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
available as properties instead of parameterless accessor methods as in Java.
The performance-enhancing methods to which you can pass an already created
object are prefixed with `Get`, e.g.:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
    // property
    var pos = monster.Pos;

    // method filling a preconstructed object
    var preconstructedPos = new Vec3();
    monster.GetPos(preconstructedPos);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

## Storing dictionaries in a FlatBuffer

FlatBuffers doesn't support dictionaries natively, but there is support to
emulate their behavior with vectors and binary search, which means you
can have fast lookups directly from a FlatBuffer without having to unpack
your data into a `Dictionary` or similar.

To use it:
-   Designate one of the fields in a table as they "key" field. You do this
    by setting the `key` attribute on this field, e.g.
    `name:string (key)`.
    You may only have one key field, and it must be of string or scalar type.
-   Write out tables of this type as usual, collect their offsets in an
    array.
-   Instead of calling standard generated method,
    e.g.: `Monster.createTestarrayoftablesVector`,
    call `CreateMySortedVectorOfTables` in C# or
    `createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
    which will first sort all offsets such that the tables they refer to
    are sorted by the key field, then serialize it.
-   Now when you're accessing the FlatBuffer, you can use `LookupByKey`
    to access elements of the vector, e.g.:
    `Monster.lookupByKey(tablesVectorOffset, "Frodo", dataBuffer)`,
    which returns an object of the corresponding table type,
    or `null` if not found.
    `LookupByKey` performs a binary search, so should have a similar speed to
    `Dictionary`, though may be faster because of better caching. `LookupByKey`
    only works if the vector has been sorted, it will likely not find elements
    if it hasn't been sorted.

## Text parsing

There currently is no support for parsing text (Schema's and JSON) directly
from Java or C#, though you could use the C++ parser through native call
interfaces available to each language. Please see the
C++ documentation for more on text parsing.

<br>
