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

二进制配置文件为什么比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/guanfeng/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;
}

结果为

时间: 2024-12-25 08:25:38

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

Android配置文件分享和JSON数据生成与解析

首先声明,我这里大体是讲的一个关于"Android配置文件分享和JSON数据生成与解析"的整体流程,具体数据库中的数据根据读者自己的项目来安排,如果您看不大懂也请您原谅,毕竟我说了,我只是新手.其实关于数据库中的数据你只需要知道他们都是一个个对象,然后有各自的属性就行了,我们的关键在于JSON数据的生成与解析. 鉴于自己的是个博客新手,感觉自己的博客访问量有些少可能是因为自己确实知识匮乏,毕竟我早就说了,我不适合编程,但是没办法啊,我要去读个文学博士的话,怕是要遭人白眼了,故而以后的事

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

一.项目配置文件project.config.json 小程序开发者工具在每个项目的根目录都会生成一个 project.config.json,在工具上做的任何配置都会写入到这个文件,当重新安装工具或者换电脑工作时,只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,其中会包括编辑器的颜色.代码上传时自动压缩等等一系列选项. 可以在项目根目录使用 project.config.json 文件对项目进行配置. (1)compileType 有效值: (2)sett

tsconfig.json ts配置文件解析

tsconfig.json ts配置文件解析 tsconfig 编译选项 示例配置: { "compilerOptions": { //指定生成哪个模块系统代码: "None", "CommonJS", "AMD", "System", "UMD", "ES6"或 "ES2015". "module": "common

C# 二进制、Xml、Json序列化和反序列化

昨天利用业余时间对比了下C#中三种序列化方式(二进制.Xml.Json),综合来看json方式生成的字节数组长度最短,但当你需要序列化的对象中包括byte[]类型,且其长度较长时,序列化后,xml方式的长度较json方式更短.xml方式中对byte[]做了base64转换. 最后综合三种情况,写了一个基于泛型的通用类来完成序列化和反序列化操作,仅供参考,若有什么错误之处,还请指教. using System; using System.Collections.Generic; using Sys

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

Spring <context:property-placeholder/> 期望:能不能有一种解决方案可以方便我们在一个阶段内不需要频繁书写一个参数的值,而在不同阶段间又可以方便的切换参数配置信息 解决:spring3中提供了一种简便的方式就是context:property-placeholder/元素 只需要在spring的配置文件里添加一句:<context:property-placeholder location="classpath:jdbc.properties

Log4j配置文件位置+Spring中数据源配置文件位置

一.Log4j配置文件位置 1.自动加载 应用程序启动时,默认情况下会到src目录下寻找log4j.xml配置文件,若不存在,会继续寻找log4j.properties文件,只要找到其中一个就会加载该配置文件内容. 2.手动加载 如果将log4j.properties(或log4j.xml)放到其它目录下,比如下图中的位置,应用程序就不能自动加载log4j的配置文件了,因为应用程序找不到该配置文件,你需要手动加载. 需要在应用程序启动的代码中加入如下的代码: //加载config文件夹下的log

mybatis源码-解析配置文件(三)之配置文件Configuration解析(超详细, 值得收藏)

1. 简介 1.1 系列内容 本系列文章讲解的是mybatis解析配置文件内部的逻辑, 即 Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); 其背后的逻辑. 1.2 适合对象 了解如何使用 mybatis 来访问数据库.可参看<

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

在 mybatis源码-解析配置文件(三)之配置文件Configuration解析 中, 讲解了 Configuration 是如何解析的. 其中, mappers作为configuration节点的一部分配置, 在本文章中, 我们讲解解析mappers节点, 即 xxxMapper.xml 文件的解析. 1 解析入口 在解析 mybatis-config.xml 时, 会进行解析 xxxMapper.xml 的文件. 在图示流程的 XMLConfigBuilder.parse() 函数中, 该

答:SQLServer DBA 三十问之一: char、varchar、nvarchar之间的区别(包括用途和空间占用);xml类型查找某个节点的数据有哪些方法,哪个效率高;使用存储 过程和使用T-SQL查询数据有啥不一样;

http://www.cnblogs.com/fygh/archive/2011/10/18/2216166.html 1. char.varchar.nvarchar之间的区别(包括用途和空间占用):xml类型查找某个节点的数据有哪些方法,哪个效率高:使用存储 过程和使用T-SQL查询数据有啥不一样: ------------------------------------------------ SQL中char.varchar.nchar.nvarchar的区别 http://www.cn