FlatBuffers相对于ProBuffer的性能差异网上资料很多,这里暂时不做讨论。先用一个简单的例子来讨论简单的FlatBuffers的用法。
namespace MyGame;
enum PhoneType : int {
MOBILE = 0,
HOME = 1,
WORK = 2,
}
table PhoneNumber {
number:string (required);
type:int;
}
table People {
name:string;
age:int;
phone:[PhoneNumber];
}
table AddressBook {
people:[People];
}
root_type AddressBook;
上面是生成代码的描述文件,保存为Sample.fbs.
执行命令行: flatc.exe --csharp -o Resource/Sample Sample.fbs
则可以生成目标语言的代码。
–csharp指定了编译的目标语言。-o则用于指定输出文件路径,如果没有提供则将当前目录作为输出目录。最后是fbs文件名。
详细说明见官方文档。
新建一个win32的工程文件,引入对应语言的库文件(可以编译成dll文件放入工程,也可以直接拷贝git里面的源代码)。引入刚刚生成的文件。准备完毕。
这一步的目标是生成需要的二进制文件,并读取生成的二进制然后显示是否正确。
Encode的代码如下:
static byte[] EncodeTest(string[] names)
{
FlatBufferBuilder fbBuilder = new FlatBufferBuilder(1);
Offset[] personOffsets = new Offset[names.Length];
for (int i = 0; i < names.Length; i++)
{
var phoneOffsets = new Offset[3];
for (int j = 0; j < 3; j++)
{
string formatPhoneNumber = string.Format("{0:D11}", 10000000000 + j + i * 3);
var phoneNumber = fbBuilder.CreateString(formatPhoneNumber);
var phoneOffset = PhoneNumber.CreatePhoneNumber(fbBuilder, phoneNumber, j);
phoneOffsets[j] = phoneOffset;
}
var pOffset = People.CreatePhoneVector(fbBuilder, phoneOffsets);
var name = fbBuilder.CreateString(names[i]);
var peopleOffset = People.CreatePeople(fbBuilder, name, 100 + i, pOffset);
personOffsets[i] = peopleOffset;
}
var offset = AddressBook.CreatePeopleVector(fbBuilder, personOffsets);
AddressBook.StartAddressBook(fbBuilder);
AddressBook.AddPeople(fbBuilder, offset);
var eab = AddressBook.EndAddressBook(fbBuilder);
AddressBook.FinishAddressBookBuffer(fbBuilder, eab);
return fbBuilder.SizedByteArray();
}
Decode的代码如下:
static AddressBook DecodeTest(byte[] datas)
{
ByteBuffer byteBuffer = new ByteBuffer(datas);
return AddressBook.GetRootAsAddressBook(byteBuffer);
}
构造假数据并打印的代码如下:
static void Main(string[] args)
{
while (true)
{
ConsoleKey inputKey = Console.ReadKey().Key;
if (inputKey == ConsoleKey.A)
{
Console.WriteLine("\n");
string[] names = new string[100];
for (int i = 0; i < 100; i++)
{
string formatName = string.Format("PeopleName{0:D9}", i + 1);
Console.WriteLine(formatName);
names[i] = formatName;
}
byte[] encodeBytes = EncodeTest(names);
File.WriteAllBytes(@"AddressBook.ab", encodeBytes);
}
if (inputKey == ConsoleKey.B)
{
Console.WriteLine("\nFlatBuffers info:");
var bytes = File.ReadAllBytes(@"AddressBook.ab");
AddressBook addressBook = DecodeTest(bytes);
int size = addressBook.PeopleLength;
for (int j = 0; j < size; j++)
{
People? people = addressBook.People(j);
if (people != null)
{
Console.WriteLine("Name:{0},Age:{1}", people.Value.Name, people.Value.Age);
int pSize = people.Value.PhoneLength;
for (int k = 0; k < pSize; k++)
{
PhoneNumber? phoneNumber = people.Value.Phone(k);
if (phoneNumber != null)
{
Console.WriteLine("Phone Type,Number:{0},{1}", phoneNumber.Value.Type, phoneNumber.Value.Number);
}
}
}
}
}
}
}
运行上面的代码即可构造生成一个二进制文件并打印出里面的内容。
利用命令行 flatc.exe --raw-binary -t Sample.fbs -- AddressBook.ab
可以生成一个名字叫AddressBook.json的文件,方面查看生成的二进制文件内容是否正确。
注意:AddressBook.ab前面有一个空格。