二进制配置文件为什么比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进行二进制文件读写 

FormatC TypePython字节数
xpad byteno value1
ccharstring of length 11
bsigned charinteger1
Bunsigned charinteger1
?_Boolbool1
hshortinteger2
Hunsigned shortinteger2
iintinteger4
Iunsigned intinteger or long4
llonginteger4
Lunsigned longlong4
qlong longlong8
Qunsigned long longlong8
ffloatfloat4
ddoublefloat8
schar[]string1
pchar[]string1
Pvoid *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;
}

结果为

转载于:https://www.cnblogs.com/BigFeng/p/5003904.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将程序参数保存到本地的方式有很多种,不同的方式适用于不同的场景。下面介绍几种高效率的保存程序参数到本地的方式: 1. 使用INI文件 INI文件是一种文本文件,通常用于保存程序的配置参数。INI文件可以使用键值对的方式保存参数,可以使用C语言中的`ini`库读写INI文件。使用INI文件保存程序参数的方式如下: ```ini [param] param1=10 param2=20 ``` 在上面的INI文件中,使用`param`作为段的名称,使用`param1`和`param2`作为参数的键名,值分别为10和20。 2. 使用JSON文件 JSON文件是一种轻量级的数据交换格式,可以使用C语言中的`cJSON`库读写JSON文件。使用JSON文件保存程序参数的方式如下: ```json { "param1": 10, "param2": 20 } ``` 在上面的JSON文件中,使用`param1`和`param2`作为参数的键名,值分别为10和20。 3. 使用二进制文件 二进制文件是一种文件格式,可以直接将程序参数以二进制的方式写入文件,读取时再以二进制的方式读取。使用二进制文件保存程序参数的方式如下: ```c #include <stdio.h> int main() { int param1 = 10, param2 = 20; // 打开文件 FILE* fp = fopen("params.bin", "wb"); if (fp == NULL) { printf("无法打开文件\n"); return 1; } // 将参数写入文件 fwrite(&param1, sizeof(int), 1, fp); fwrite(&param2, sizeof(int), 1, fp); // 关闭文件 fclose(fp); return 0; } ``` 在上面的代码中,我们使用`fopen()`函数打开了一个名为`params.bin`的文件,并以二进制写入模式`"wb"`打开。然后,我们使用`fwrite()`函数将参数写入文件。最后,我们使用`fclose()`函数关闭文件。 总的来说,使用INI文件或JSON文件保存程序参数的方式更为直观和灵活,但是在大量数据的情况下,使用二进制文件更为高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值