二进制配置文件为什么比json等配置文件高效

项目中用spine做动画,spine可以导出json和二进制的动画配置文件,蛋疼的是spine官方竟然没有提供c的二进制配置解析代码,更没有提供它二进制文件的格式说明。为了动画加载的更快,只能自己把json用python转成二进制文件(格式自定),再自行实现解析二进制的c代码了。经过小心谨慎的代码实现后,测试结果是二进制配置文件比json文件大小小了1半以上,并且动画创建速度快1倍以上。下文简单总结了一下二进制配置文件的优点。

1.什么是二进制配置文件

当然,一切文件在计算机中都是以二进制(01)格式存储的,那么二进制配置文件是指什么呢?比如要存储

{
"time" = 133,
"color" = [233, 0, 0],
"pos" = [34, 22]
}

json一般以utf-8格式保存成文本,那么什么是utf-8呢?它是unicode编码的一种实现形式,具体解释请参考UTF-8编码规则(转)中日韩uincode编码参考。也就是说,像程序中的数字类型133,233,22等,一个uint8就能存储下了,可是133在json中却占了3个字节,要是存个12.432312等数据要占用更多的空间。而本文所说的二进制配置,直接存133等的uint8二进制编码0x85,这样便减少了一部分文件大小。编码与解码可以商量好,比如time,编解码都以t代替,又可以节省一部分空间,甚至可以不存储time,color,pos等key,直接顺序在配置中写value,解码时直接读value(为了说的清楚,后面的例子保留了key)这样又可以减少配置文件的大小。

2.二进制配置文件优点与缺点

优点已经说了,2个优点:文件小、解析快。为啥文件小上面已经说了。至于为啥解析快呢,首先,因为文件小,io时间需要的就少。其次,少了把配置文件解析成json对象或xml对象的中间步骤,直接读这个二进制文件就可以,我觉得顺着读二进制文件可以达到最快的速度。

缺点也有2个:难以直接查看、通用性差。json或xml等配置文件可以直接看出来配置的是神马,可是这个二进制就啥也看不出来了。通用性差是因为要达到高效的解析,最好顺着解析,捋一遍配置文件就完了,所以解析二进制的代码难以公用。

3.读写二进制例子

比如上面的那个json文件,怎么搞成二进制配置呢,可以先规定好数据的类型,比如s为string,i为number,f为float。string还要告诉解析时字符串有多长,比如time就是s4time。上面的例子要写二进制就是s4timei133s5colori244i0i0s3posi34i22,这肯定不是最优的,就是为了说明怎么读写二进制而已。

(1)python写二进制文件

python写二进制文件用到了 struct.pack,读二进制用 struct.unpack(),具体怎用用struct请参考 使用Python进行二进制文件读写

Format C Type Python 字节数
x pad byte no value 1
c char string of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer or long 4
l long integer 4
L unsigned long long 4
q long long long 8
Q unsigned long long long 8
f float float 4
d double float 8
s char[] string 1
p char[] string 1
P void * long 
import struct

def writeBinary():
binaryFile = open(r"./binary.obj","wb");
binaryFile.write(struct.pack("i", 4));
binaryFile.write(struct.pack("4s", "time"));
binaryFile.write(struct.pack("i", 133));
binaryFile.write(struct.pack("i", 5));
binaryFile.write(struct.pack("5s", "color")); if __name__ == "__main__":
writeBinary();

执行完会产生下面的二进制文件

(2)c++读二进制文件

#include <iostream>

using namespace std;

char * data = nullptr;

char * getFileContent(const char * filePath) {
FILE *pFile=fopen(filePath, "r");
char * pBuf;
fseek(pFile, 0, SEEK_END);
int len = ftell(pFile);
pBuf = new char[len+1];
rewind(pFile);
fread(pBuf, 1, len, pFile);
pBuf[len] = 0;
fclose(pFile);
return pBuf;
} int8_t readByte() {
return (int8_t)*data++;
} int32_t readInt() {
int32_t val = 0;
char * pd = (char*)&val;
*pd = readByte();
*(pd + 1) = readByte();
*(pd + 2) = readByte();
*(pd + 3) = readByte();
return (int32_t)val;
} std::string readString() {
int32_t strLen = readInt();
std::string str = std::string(data, strLen);
data = data + strLen;
return str;
} int main() {
data = getFileContent("/Users/abc/PycharmProjects/BinaryTest/binary.obj"); std::string timeStr = readString(); int timeValue = readInt(); std::string colorStr = readString(); std::cout << "timeStr is " << timeStr << std::endl;
std::cout << "colorStr is " << colorStr << std::endl;
std::cout << "timeValue is " << timeValue << std::endl; free(data); return 0;
}

结果为

二进制配置文件为什么比json等配置文件效率高的更多相关文章

  1. 微信小游戏 项目配置文件 project.config.json

    一.项目配置文件project.config.json 小程序开发者工具在每个项目的根目录都会生成一个 project.config.json,在工具上做的任何配置都会写入到这个文件,当重新安装工具或 ...

  2. python接口自动化读取json,yaml配置文件+封装requests+unittest+HTMLRunner实现全自动化

    # coding=utf-8 import json import requests class TestApi(object): """ /* @param: @ses ...

  3. [08]ASP.NET Core 中 launchsettings.json 启动配置文件

    ASP.NET Core launchsettings.json 启动配置文件 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自 ...

  4. .netcore项目codefirst时使用的配置文件是appsettings.json

    .netcore项目创建完毕后,会发现项目中有好几个配置文件: appsettings.json appsettings.Development.json appsettings.Production ...

  5. ThinkPHP公共配置文件与各自项目中配置文件组合的方法

    ThinkPHP公共配置文件与各自项目中配置文件组合的方法 文章TAG:thinkphp 公共配置文件 时间:2014-11-25来源:www.aspku.com 作者:源码库 文章热度: 146 ℃ ...

  6. 【配置文件节点】java世界配置文件节点

    Spring <context:property-placeholder/> 期望:能不能有一种解决方案可以方便我们在一个阶段内不需要频繁书写一个参数的值,而在不同阶段间又可以方便的切换参 ...

  7. mybatis源码-解析配置文件(四)之配置文件Mapper解析

    在 mybatis源码-解析配置文件(三)之配置文件Configuration解析 中, 讲解了 Configuration 是如何解析的. 其中, mappers作为configuration节点的 ...

  8. jar包读取jar包内部和外部的配置文件,springboot读取外部配置文件的方法

    jar包读取jar包内部和外部的配置文件,springboot读取外部配置文件的方法 用系统属性System.getProperty("user.dir")获得执行命令的目录(网上 ...

  9. mybatis源码-解析配置文件(三)之配置文件Configuration解析

    目录 1. 简介 1.1 系列内容 1.2 适合对象 1.3 本文内容 2. 配置文件 2.1 mysql.properties 2.2 mybatis-config.xml 3. Configura ...

随机推荐

  1. Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)

    http://www.xuebuyuan.com/558284.html 方法一 public class MainActivity extends Activity { @Override prot ...

  2. floating IP 原理分析 - 每天5分钟玩转 OpenStack(107)

    上一节我们通过 Web UI 创建为 cirros-vm3 分配了浮动 IP,今天将分析其工作原理. 首先查看 router 的 interface 配置: 可以看到,floating IP 已经配置 ...

  3. WebAPi返回类型到底应该是什么才合适,这是个问题?

    前言 有些问题只有真正遇到或者用到并且多加思考才会想到,平常若作为自学的心态去学习则不会考虑太多,我慢慢明白对于那些有太多要学的东西或者说的更加明确而且具体一点的话,如果对于你现在不是迫切要学或者需要 ...

  4. MySQL半同步复制

    从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认的复制即是 ...

  5. 如何用perl将表格中不同列的数据进行拼凑,然后将拼凑后的数据用“|”连接在一起

    最近写了一个perl脚本,实现的功能是将表格中其中两列的数据进行拼凑,然后将拼凑后的数据用“|”连接在一起. 表格内容如下: 员工号码 员工姓名 职位 入职日期 1001 张三 销售 1980/12/ ...

  6. 小菜学习Winform(六)剪切板和拖放复制

    前言 在做winform项目的时候有时候会用到复制粘贴,在.net中提供了Clipboard类来操作剪切板,我们来看下. clipbrd.exe clipbrd是系统剪切板程序,但是在vista及以上 ...

  7. 小菜学习Winform(四)MDI窗体(附示例)

    前言 在做winfrom项目的时候我们可能会用到嵌套窗体,就是说一个容器中有多个窗体,可以分别管理和应用这些窗体,.net中提供了一种机制就是MDI,可能大家都会用,这边就简单的介绍下. 简单应用 w ...

  8. 10个惊艳的Swift单行代码

    几年前,一篇表述“10个Scala函数式单行代码”的文章非常受欢迎,并且随后立马出现了其他的语言版本,例如Haskell版本,Ruby版本,Groovy版本,Clojure版本,Python版本,C# ...

  9. react入门(2)

    接着上一次的讲,如果没有看过上一篇文章的小伙伴可以先看一下http://www.cnblogs.com/sakurayeah/p/5807821.html React事件 可以先看一下官网讲解的内容h ...

  10. Sql数据库查询当前环境有无死锁

    DECLARE @spid INT , @bl INT , @intTransactionCountOnEntry INT , @intRowcount INT , @intCountProperti ...