1Use in Java/C#    {#flatbuffers_guide_use_java_c-sharp}
2==============
3
4## Before you get started
5
6Before diving into the FlatBuffers usage in Java or C#, it should be noted that
7the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
8general FlatBuffers usage in all of the supported languages (including both Java
9and C#). This page is designed to cover the nuances of FlatBuffers usage,
10specific to Java and C#.
11
12You should also have read the [Building](@ref flatbuffers_guide_building)
13documentation to build `flatc` and should be familiar with
14[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
15[Writing a schema](@ref flatbuffers_guide_writing_schema).
16
17## FlatBuffers Java and C-sharp code location
18
19#### Java
20
21The code for the FlatBuffers Java library can be found at
22`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
23[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
24java/com/google/flatbuffers).
25
26#### C-sharp
27
28The code for the FlatBuffers C# library can be found at
29`flatbuffers/net/FlatBuffers`. You can browse the library on the
30[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
31FlatBuffers).
32
33## Testing the FlatBuffers Java and C-sharp libraries
34
35The code to test the libraries can be found at `flatbuffers/tests`.
36
37#### Java
38
39The test code for Java is located in [JavaTest.java](https://github.com/google
40/flatbuffers/blob/master/tests/JavaTest.java).
41
42To run the tests, use either [JavaTest.sh](https://github.com/google/
43flatbuffers/blob/master/tests/JavaTest.sh) or [JavaTest.bat](https://github.com/
44google/flatbuffers/blob/master/tests/JavaTest.bat), depending on your operating
45system.
46
47*Note: These scripts require that [Java](https://www.oracle.com/java/index.html)
48is installed.*
49
50#### C-sharp
51
52The test code for C# is located in the [FlatBuffers.Test](https://github.com/
53google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
54tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
55https://www.visualstudio.com), and compile/run the project.
56
57Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
58Once you have installed `Mono`, you can run the tests from the command line
59by running the following commands from inside the `FlatBuffers.Test` folder:
60
61~~~{.sh}
62  mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
63  mono Assert.exe
64~~~
65
66## Using the FlatBuffers Java (and C#) library
67
68*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
69example of how to use FlatBuffers in Java or C#.*
70
71FlatBuffers supports reading and writing binary FlatBuffers in Java and C#.
72
73To use FlatBuffers in your own code, first generate Java classes from your
74schema with the `--java` option to `flatc`. (Or for C# with `--csharp`).
75Then you can include both FlatBuffers and the generated code to read
76or write a FlatBuffer.
77
78For example, here is how you would read a FlatBuffer binary file in Java:
79First, import the library and generated code. Then, you read a FlatBuffer binary
80file into a `byte[]`.  You then turn the `byte[]` into a `ByteBuffer`, which you
81pass to the `getRootAsMyRootType` function:
82
83*Note: The code here is written from the perspective of Java. Code for both
84languages is both generated and used in nearly the exact same way, with only
85minor differences. These differences are
86[explained in a section below](#differences_in_c-sharp).*
87
88~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
89    import MyGame.Example.*;
90    import com.google.flatbuffers.FlatBufferBuilder;
91
92    // This snippet ignores exceptions for brevity.
93    File file = new File("monsterdata_test.mon");
94    RandomAccessFile f = new RandomAccessFile(file, "r");
95    byte[] data = new byte[(int)f.length()];
96    f.readFully(data);
97    f.close();
98
99    ByteBuffer bb = ByteBuffer.wrap(data);
100    Monster monster = Monster.getRootAsMonster(bb);
101~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102
103Now you can access the data from the `Monster monster`:
104
105~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
106    short hp = monster.hp();
107    Vec3 pos = monster.pos();
108~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109
110<a name="differences_in_c-sharp">
111#### Differences in C-sharp
112</a>
113
114C# code works almost identically to Java, with only a few minor differences.
115You can see an example of C# code in
116`tests/FlatBuffers.Test/FlatBuffersExampleTests.cs` or
117`samples/SampleBinary.cs`.
118
119First of all, naming follows standard C# style with `PascalCasing` identifiers,
120e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
121available as properties instead of parameterless accessor methods as in Java.
122The performance-enhancing methods to which you can pass an already created
123object are prefixed with `Get`, e.g.:
124
125~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
126    // property
127    var pos = monster.Pos;
128
129    // method filling a preconstructed object
130    var preconstructedPos = new Vec3();
131    monster.GetPos(preconstructedPos);
132~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133
134## Storing dictionaries in a FlatBuffer
135
136FlatBuffers doesn't support dictionaries natively, but there is support to
137emulate their behavior with vectors and binary search, which means you
138can have fast lookups directly from a FlatBuffer without having to unpack
139your data into a `Dictionary` or similar.
140
141To use it:
142-   Designate one of the fields in a table as the "key" field. You do this
143    by setting the `key` attribute on this field, e.g.
144    `name:string (key)`.
145    You may only have one key field, and it must be of string or scalar type.
146-   Write out tables of this type as usual, collect their offsets in an
147    array.
148-   Instead of calling standard generated method,
149    e.g.: `Monster.createTestarrayoftablesVector`,
150    call `CreateSortedVectorOfMonster` in C# or
151    `createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
152    which will first sort all offsets such that the tables they refer to
153    are sorted by the key field, then serialize it.
154-   Now when you're accessing the FlatBuffer, you can use
155    the `ByKey` accessor to access elements of the vector, e.g.:
156    `monster.testarrayoftablesByKey("Frodo")` in Java or
157    `monster.TestarrayoftablesByKey("Frodo")` in C#,
158    which returns an object of the corresponding table type,
159    or `null` if not found.
160    `ByKey` performs a binary search, so should have a similar
161    speed to `Dictionary`, though may be faster because of better caching.
162    `ByKey` only works if the vector has been sorted, it will
163    likely not find elements if it hasn't been sorted.
164
165## Text parsing
166
167There currently is no support for parsing text (Schema's and JSON) directly
168from Java or C#, though you could use the C++ parser through native call
169interfaces available to each language. Please see the
170C++ documentation for more on text parsing.
171
172<br>
173