FlatBuffers初探(C#为例)

一. 前言

FlatBuffers相对于ProBuffer的性能差异网上资料很多,这里暂时不做讨论。先用一个简单的例子来讨论简单的FlatBuffers的用法。

二. Schema (IDL, Interface Definition Language)

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.

三. Generate Code

执行命令行: flatc.exe --csharp -o Resource/Sample Sample.fbs 则可以生成目标语言的代码。

–csharp指定了编译的目标语言。-o则用于指定输出文件路径,如果没有提供则将当前目录作为输出目录。最后是fbs文件名。

详细说明见官方文档。

四. 工程文件准备

新建一个win32的工程文件,引入对应语言的库文件(可以编译成dll文件放入工程,也可以直接拷贝git里面的源代码)。引入刚刚生成的文件。准备完毕。

五. Generate Binary 然后直接读取二进制

这一步的目标是生成需要的二进制文件,并读取生成的二进制然后显示是否正确。

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

运行上面的代码即可构造生成一个二进制文件并打印出里面的内容。

六. 通过二进制文件生成Json文件,方便查看

利用命令行 flatc.exe --raw-binary -t Sample.fbs -- AddressBook.ab 可以生成一个名字叫AddressBook.json的文件,方面查看生成的二进制文件内容是否正确。

注意:AddressBook.ab前面有一个空格。

完毕!

你可能感兴趣的:(c#,开发心得,开发工具,FlatBuffers)