FlatBuffers是Google开源的一个跨平台的、高效的、提供了C++/Java接口的序列化工具库,它是Google专门为游戏开发或其余性能敏感的应用程序需求而建立。尤为适用移动,嵌入式平台,这些平台在内存大小及带宽相比桌面系统都是受限的,而应用程序好比游戏又有更高的性能要求。它将序列化数据存储在缓存中,这些数据既能够存储在文件中,又能够经过网络原样传输,而不须要任何解析开销。如下是项目地址: 代码托管主页:github.com/google/flat… 项目介绍主页:google.github.io/flatbuffers…html
相比传统的JSON和Protocol Buffers等序列化工具,FlatBuffers具备以下的一些优势:java
Protocol Buffers的确和FlatBuffers比较相似,但其主要区别在于FlatBuffers在访问数据前不须要解析/拆包这一步,并且Protocol Buffers既没有可选的文本导入/导出功能,也没有Schemas语法特性(好比union)。git
JSON是一种轻量级的数据交换格式,JSON 能够将 JavaScript 对象中表示的一组数据转换为字符串,而后就能够在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。JSON和动态类型语言(如JavaScript)一块儿使用时很是方便。然而在静态类型语言中序列化数据时,JSON不但具备运行效率低的明显缺点,并且会让你写更多的代码来访问数据。github
首先来看一下FlatBuffers项目为开发者提供了哪些内容,能够从官网下载源码,其目录结构以下图: json
就像Parcel和Serializable的序列化同样,FlatBuffers的是使用方式上也比最传统的JSON序列化要复杂的多。在实际上面开发中,为了下降开发的难度,提升开发效率,咱们会将源码编译成可植入的第三方库。下面以Java环境为例,来介绍FlatBuffers的简单使用方法。读者能够到对应的maven仓库下载。缓存
如今,假如咱们拿到的json文件的格式是下面这样的:bash
{
"repos": [
{
"id": 27149168,
"name": "acai",
"full_name": "google/acai",
"owner": {
"login": "google",
"id": 1342004,
...
"type": "Organization",
"site_admin": false
},
"private": false,
"html_url": "https://github.com/google/acai",
"description": "Testing library for JUnit4 and Guice.",
...
"watchers": 21,
"default_branch": "master"
},
...
]
}
复制代码
注:能够经过下面的连接来获取更完整的json对象服务器
咱们须要准备一个model文件,它定义了咱们想要序列化/反序列化 的数据结构,这个模式将被flatc用于建立Java模型以及从JSON到FlatBuffer二进制文件的转换。网络
如今,咱们所要作的全部事情就是建立3个表:ReposList,Repo和User,并定义root_type。例如:数据结构
table ReposList {
repos : [Repo];
}
table Repo {
id : long;
name : string;
full_name : string;
owner : User;
//...
labels_url : string (deprecated);
releases_url : string (deprecated);
}
table User {
login : string;
id : long;
avatar_url : string;
gravatar_id : string;
//...
site_admin : bool;
}
root_type ReposList;
复制代码
注:完整的模式文件能够点击下面的连接来获取
接下来,咱们所须要作的就是将repos_json.json转换为FlatBuffers二进制文件,并产生Java模型,其能够以Java友好的方式表示咱们的数据,下面是转换的命令:
$ ./flatc -j -b repos_schema.fbs repos_json.json
复制代码
若是没有任何报错,将会生成以下4个文件:
repos_json.bin (将被重命名为repos_flat.bin)
Repos/Repo.java
Repos/ReposList.java
Repos/User.java
复制代码
接下来,咱们可使用FlatBuffers提供的Java库来处理在Java中直接处理这种数据格式,此处使用须要使用到 flatbuffers-java-1.2.0-SNAPSHOT.jar。
public class MainActivity extends AppCompatActivity {
@Bind(R.id.tvFlat)
TextView tvFlat;
@Bind(R.id.tvJson)
TextView tvJson;
private RawDataReader rawDataReader;
private ReposListJson reposListJson;
private ReposList reposListFlat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
rawDataReader = new RawDataReader(this);
}
@OnClick(R.id.btnJson)
public void onJsonClick() {
rawDataReader.loadJsonString(R.raw.repos_json).subscribe(new SimpleObserver<String>() {
@Override
public void onNext(String reposStr) {
parseReposListJson(reposStr);
}
});
}
private void parseReposListJson(String reposStr) {
long startTime = System.currentTimeMillis();
reposListJson = new Gson().fromJson(reposStr, ReposListJson.class);
for (int i = 0; i < reposListJson.repos.size(); i++) {
RepoJson repo = reposListJson.repos.get(i);
Log.d("FlatBuffers", "Repo #" + i + ", id: " + repo.id);
}
long endTime = System.currentTimeMillis() - startTime;
tvJson.setText("Elements: " + reposListJson.repos.size() + ": load time: " + endTime + "ms");
}
@OnClick(R.id.btnFlatBuffers)
public void onFlatBuffersClick() {
rawDataReader.loadBytes(R.raw.repos_flat).subscribe(new SimpleObserver<byte[]>() {
@Override
public void onNext(byte[] bytes) {
loadFlatBuffer(bytes);
}
});
}
private void loadFlatBuffer(byte[] bytes) {
long startTime = System.currentTimeMillis();
ByteBuffer bb = ByteBuffer.wrap(bytes);
reposListFlat = frogermcs.io.flatbuffs.model.flat.ReposList.getRootAsReposList(bb);
for (int i = 0; i < reposListFlat.reposLength(); i++) {
Repo repos = reposListFlat.repos(i);
Log.d("FlatBuffers", "Repo #" + i + ", id: " + repos.id());
}
long endTime = System.currentTimeMillis() - startTime;
tvFlat.setText("Elements: " + reposListFlat.reposLength() + ": load time: " + endTime + "ms");
}
}
复制代码
在上面的示例代码中,有两个方法是比较核心的,须要咱们注意。
下面咱们来测试下FlatBuffers和传统的json在数据解析上的耗时,咱们以4mb的JSON文件为例。