前段时间刚试用了一个序列化工具cereal,请看cereal:C++实现的开源序列化库,打算再总结下我对google proto buf序列化库的使用呢,

结果还没动手,大Google又出了一个新的、开源、跨平台的序列化工具:FlatBuffers。那就索性先了解了解这个工具把。

一. 什么是Google FlatBuffers

FlatBuffers是一个开源的、跨平台的、高效的、提供了C++/Java接口的序列化工具库。它是Google专门为游戏开发或其他性能敏感的应用程序需求而创建。尤其更适用于移动平台,这些平台上内存大小及带宽相比桌面系统都是受限的,而应用程序比如游戏又有更高的性能要求。它将序列化数据存储在缓存中,这些数据既可以存储在文件中,又可以通过网络原样传输,而不需要任何解析开销。

代码托管主页:https://github.com/google/flatbuffers

项目介绍主页:http://google.github.io/flatbuffers/index.html

二. 为什么要使用Google FlatBuffers

  1. 对序列化数据的访问不需要打包和拆包——它将序列化数据存储在缓存中,这些数据既可以存储在文件中,又可以通过网络原样传输,而没有任何解析开销;
  2. 内存效率和速度——访问数据时的唯一内存需求就是缓冲区,不需要额外的内存分配。 这里可查看详细的基准测试
  3. 扩展性、灵活性——它支持的可选字段意味着不仅能获得很好的前向/后向兼容性(对于长生命周期的游戏来说尤其重要,因为不需要每个新版本都更新所有数据);
  4. 最小代码依赖——仅仅需要自动生成的少量代码和一个单一的头文件依赖,很容易集成到现有系统中。再次,看基准部分细节;
  5. 强类型设计——尽可能使错误出现在编译期,而不是等到运行期才手动检查和修正;
  6. 使用简单——生成的C++代码提供了简单的访问和构造接口;而且如果需要,通过一个可选功能可以用来在运行时高效解析Schema和类JSON格式的文本;
  7. 跨平台——支持C++11、Java,而不需要任何依赖库;在最新的gcc、clang、vs2010等编译器上工作良好;

三. 为什么不使用Protocol Buffers的,或者JSON

Protocol Buffers的确和FlatBuffers比较类似,但其主要区别在于FlatBuffers在访问数据前不需要解析/拆包这一步。 而且Protocol Buffers既没有可选的文本导入/导出功能,也没有Schemas语法特性(比如union)。

JSON是非常可读的,而且当和动态类型语言(如JavaScript)一起使用时非常方便。然而在静态类型语言中序列化数据时,JSON不但具有运行效率低的明显缺点,而且会让你写更多的代码来访问数据(这个与直觉相反)。

想了解更多关于FlatBuffers的“为什么”请访问flatbuffers白皮书

四. 内建的数据类型

  • 8 bit: byte ubyte bool
  • 16 bit: short ushort
  • 32 bit: int uint float
  • 64 bit: long ulong double
  • Vector of any other type (denoted with [type]). Nesting vectors is not supported, instead you can wrap the inner vector in a table.
  • string, which may only hold UTF-8 or 7-bit ASCII. For other text encodings or general binary data use vectors ([byte] or [ubyte]) instead.
  • References to other tables or structs, enums or unions.

详细介绍请参考:schema语法格式

五. 如何使用

  1. 编写一个用来定义你想序列化的数据的schema文件(又称IDL),数据类型可以是各种大小的int、float,或者是string、array,或者另一对象的引用,甚至是对象集合;
  2. 各个数据属性都是可选的,且可以设置默认值。
  3. 使用FlatBuffer编译器flatc生成C++头文件或者Java类,生成的代码里额外提供了访问、构造序列化数据的辅助类。生成的代码仅仅依赖flatbuffers.h;请看如何生成
  4. 使用FlatBufferBuilder类构造一个二进制buffer。你可以向这个buffer里循环添加各种对象,而且很简单,就是一个单一函数调用;
  5. 保存或者发送该buffer
  6. 当再次读取该buffer时,你可以得到这个buffer根对象的指针,然后就可以简单的就地读取数据内容;

六. 一个简单的Schemas(IDL)文件

namespace zl.persons;  

enum GENDER_TYPE : byte
{
MALE = ,
FEMALE = ,
OTHER =
} table personal_info
{
id : uint;
name : string;
age : byte;
gender : GENDER_TYPE;
phone_num : ulong;
} table personal_info_list
{
info : [personal_info];
} root_type personal_info_list;

注意:这里有table、struct的区别:
table是Flatbuffers中用来定义对象的主要方式,和struct最大的区别在于:它的每个字段都是可选的(类似protobuf中的optional字段),而struct的所有成员都是required。
table除了成员名称和类型之外,还可以给成员一个默认值,如果不显式指定,则默认为0(或空)。struct不能定义scalar成员,比如说string类型的成员。在生成C++代码时,struct的成员顺序会保持和IDL的定义顺序一致,如果有必要对齐,生成器会自动生成用于对齐的额外成员。如以下Schemas代码:

struct STest
{
a : int;
b : int;
c : byte;
}

在生成为C++代码之后,会补充两个用于padding的成员__padding0与__padding1:

MANUALLY_ALIGNED_STRUCT() STest {
private:
int32_t a_;
int32_t b_;
int8_t c_;
int8_t __padding0;
int16_t __padding1; public:
STest(int32_t a, int32_t b, int8_t c)
: a_(flatbuffers::EndianScalar(a)), b_(flatbuffers::EndianScalar(b)), c_(flatbuffers::EndianScalar(c)), __padding0() {} int32_t a() const { return flatbuffers::EndianScalar(a_); }
int32_t b() const { return flatbuffers::EndianScalar(b_); }
int8_t c() const { return flatbuffers::EndianScalar(c_); }
};
STRUCT_END(STest, 12);

table的成员顺序是动态调整的,这和struct有区别。在生成C++代码时,生成器会自动调整为最佳顺序以保证它占用最小的内存空间。

七. 一个完整Demo

这里只给一个函数演示如何对对象进行序列化,完整工程请直接点击下载,或者前往github查看google_flatbuffers_test

std::string CreateOnePerson()
{
flatbuffers::FlatBufferBuilder builder;
fb_offset<fb_string> name = builder.CreateString("hello word"); zl::persons::personal_infoBuilder pib(builder);
pib.add_id();
pib.add_age();
pib.add_gender(zl::persons::GENDER_TYPE_MALE);
pib.add_name(name);
pib.add_phone_num();
flatbuffers::Offset<zl::persons::personal_info> personinfo = pib.Finish(); fb_offset<zl::persons::personal_info> info[];
info[] = personinfo; fb_offset<fb_vector<fb_offset<zl::persons::personal_info>>> info_array = fb_create_vector(builder, info, sizeof(info) / sizeof(info[]));
fb_offset<zl::persons::personal_info_list> info_list = create_personal_info_list(builder, info_array);
fb_finish(builder, info_list); // return the buffer for the caller to use.
return std::string(reinterpret_cast<const char *>(builder.GetBufferPointer()), builder.GetSize());
}

八. 其他

关于性能,除了Google公布的基准测试外,有人自己测试验证过,上面的IDL文件即来源于该作者的这篇文章

九. 参考

http://google.github.io/flatbuffers/index.html

http://powman.org/archives/md__schemas.html

http://blog.csdn.net/menggucaoyuan/article/details/34409433

http://liubin.org/2014/06/19/google-flatbuffers-cross-platform-serialization-library/

Google FlatBuffers——开源、跨平台的新一代序列化工具的更多相关文章

  1. Brackets - 强大免费的开源跨平台Web前端开发工具IDE (HTML/CSS/Javascript代码编辑器)

    Brackets 是一个免费.开源且跨平台的 HTML/CSS/JavaScript 前端 WEB 集成开发环境 (IDE工具).该项目由 Adobe 创建和维护,根据MIT许可证发布,支持 Wind ...

  2. [转载]Brackets - 强大免费的开源跨平台Web前端开发工具IDE (HTML/CSS/Javascript代码编辑器)

    http://brackets.io/ Brackets 是一个免费.开源且跨平台的 HTML/CSS/JavaScript 前端 WEB 集成开发环境 (IDE工具).该项目由 Adobe 创建和维 ...

  3. web编辑工具 - Brackets - 强大免费的开源跨平台Web前端开发工具IDE

      简单使用可以参考: https://blog.csdn.net/melon19931226/article/details/68066971/ https://www.iplaysoft.com/ ...

  4. 新一代开源Android渠道包生成工具Walle

    本文转自:http://tech.meituan.com/android-apk-v2-signature-scheme.html 新一代开源Android渠道包生成工具Walle 新的应用签名方案A ...

  5. BAT等大厂已开源的70个实用工具盘点(附下载地址)

    前面的一篇文章<微软.谷歌.亚马逊.Facebook等硅谷大厂91个开源软件盘点(附下载地址)>列举了国外8个互联网公司(包括微软.Google.亚马逊.IBM.Facebook.Twit ...

  6. .NET Core:面向未来的开源跨平台开发技术

    作为一种全新的开源和跨平台的开发平台,.NET Core 历经两年多的开发,终于在于2016年6月27日针对所有主流服务器和桌面操作系统发布 1.0 RTM 版本..NET Core 是一种通用开发平 ...

  7. C++的开源跨平台日志库glog学习研究(一)

    作为C++领域中为数不多的好用.高效的.跨平台的日志工具,Google的开源日志库glog也算是凤毛麟角了.glog 是一个C++实现的应用级日志记录框架,提供了C++风格的流操作. 恰巧趁着五一我也 ...

  8. google的开源项目总结

    转自http://www.feng5166.com/blog/424.html google的开源项目值得我们一用的,这些项目很有意义,甚至可以直接用在我们自己的工作上!学习编程的的一个比较好的方式就 ...

  9. google的开源项目总结(转载)

    转自http://www.feng5166.com/blog/424.html google的开源项目值得我们一用的,这些项目很有意义,甚至可以直接用在我们自己的工作上!学习编程的的一个比较好的方式就 ...

随机推荐

  1. 解决ASP.NET在IE10中Session丢失问题【转】

    今天发现在IE10中登录我公司的一个网站时,点击其它菜单,页面总会自动重新退出到登录页,后检查发现,IE10送出的HTTP头,和.AUTH Cookie都没问题,但使用表单验证机制(FormsAuth ...

  2. vs2013 下载

    http://download.microsoft.com/download/2/4/9/249BF223-5B84-4259-9424-429E66F45509/VS2013_RC_ULT_CHS. ...

  3. 转:VC解析XML文件-CMarkup的使用详解

    本篇文章是对VC解析XML文件-CMarkup的使用进行了详细的分析介绍,需要的朋友参考下 VC解析XML文件的工具有很多,CMarkup, tinyXML,还有IBM的,MS的等等. 据说tinyX ...

  4. Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  5. Web service standards: SOAP, REST, OData, and more

    Web service standards: SOAP, REST, OData, and more So far, we've covered the components of a web ser ...

  6. u3d动态加入模型

    楼层一层一层的加,把模型分开,弄成prefab放到Resourse文件夹里,在代码里用Instantiate(Resources.Load("模型名字") as GameObjec ...

  7. Hadoop 2.4.1 登录认证配置小结

    1.简单模式 这种模式,配置简单,使用简单. core-site.xml添加 <property> <name>hadoop.security.authorization< ...

  8. Spark源码系列(二)RDD详解

    1.什么是RDD? 上一章讲了Spark提交作业的过程,这一章我们要讲RDD.简单的讲,RDD就是Spark的input,知道input是啥吧,就是输入的数据. RDD的全名是Resilient Di ...

  9. HTML5新特性之跨文档消息传输

    1.同域限制 所谓“同域限制”是指,出于安全考虑,浏览器只允许脚本与同样协议.同样域名.同样端口的地址进行通信. 2.window.postMessage方法 浏览器限制不同窗口(包括iFrame窗口 ...

  10. android 开发环境

    http://blog.csdn.net/shulianghan/article/details/38023959