二进制配置文件为什么比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. .NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部 ...

  2. 关于SubSonic3.0插件使用SubSonic.Query.Select查询时,字段类型为tinyint时列丢失问题的Bug修复

    下午在写代码时,突然发现一个列名为Enable的字段怎么也查询不出来,开始以为可能这个名称是关键字,所以给过滤掉了,所以就将名称修改为IsEnable,问题还是一样......将名称又改为IsEnab ...

  3. iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流

    上篇博客的实例是自带的UICollectionViewDelegateFlowLayout布局基础上来做的Demo, 详情请看<iOS开发之窥探UICollectionViewControlle ...

  4. 转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)

    本文转载自CSDN的jzj1993,原文连接:http://blog.csdn.net/jzj1993/article/details/39158865 有时我们需要使用安卓实现在后台模拟系统按键,比 ...

  5. iOS homekit使用说明

    本文由CocoaChina翻译组成员iBenjamin_Go和浅夏@旧时光翻译自苹果开发文档:HomeKit Developer Guide,敬请勘误. 本文档内容包括 第一部分:简介 第二部分:启用 ...

  6. 关于C#静态变量初始化问题

    关于这个静态变量,平时自己没有太认真的去认识.最近调项目的bug,让我重新认识了静态变量的特点. 其实,我们一直都在说:静态变量只在类第一次初始化的时候进行初始化,以后都不初始化. 很简单的一句话,但 ...

  7. 关于客户端接口分页sql语句

    今天突然翻到为客户端写分页数据的sql,发现其实逻辑不对.列表是按照id降序的 当时这样写的: #翻上一页: select 字段 from 表 where id>lastId order by ...

  8. padding/border与width的关系

    本文讲述 padding / border 的设置后是否对 width 有影响,width 等于 auto 与 100% 的区别 CSS 框模型 (Box Model) 规定了元素框处理元素内容.内边 ...

  9. 在 Git 中 Checkout 历史版本

    昨天写代码的时候,误删了一个文件.今天发现的时候,commit 已经 push 到版本库了.本想用 git reset 回退版本,找回文件后重新提交.但是想起 Git 是一个版本控制系统哎,直接从版本 ...

  10. SQL Server 存储过程遇到“表 '#TT' 没有标识属性。无法执行 SET 操作”错误

    创建临时表,往临时表插入数据的时候报的错误. 一开始提示没有打开主键,后来打开主键就提示上述错误异常. 从网上查找资料没有找到,然后又到群里问各位大牛,一位大牛告诉我是没有设置主键. 我又仔细看看提示 ...