设计二进制文件格式
前言
本文是由于需要设计一种二进制的文件格式用于保存前文中所提取出来的wav文件的采样数据故而写下本篇文章。
1、为何需要一种二进制的文件格式
程序时常需要保存自身的文档数据。比如一个矢量绘图程序,需要将用户绘制的每个图元都保存到文件中,以后再次打开。应该优先考虑文本格式,文本格式容易测试和编辑。更应该优先考虑通用的文本格式,比如 XML, JSON, Lua 等等。这些通用的文本格式已经存在大量的工具和库,可以省下很多功夫。
文本格式读取慢,并且文件尺寸也比较大(就算经过 zip 压缩),大多数情况下这都不是什么问题。但一些场合,要求更快读取速度,更小文件尺寸,这时就需要自己来设计一种二进制文件格式。游戏中的模型数据,就要求读取速度快;而经常通过网络传输的文件,就要求减少文件尺寸,比如 swf 格式。
2、文件格式的具体设计
具体的二进制文件格式,要根据具体的程序需求来设计。但有些设计思路,是所有二进制格式都通用的。了解这些,对将来分析其它的二进制格式也会有帮助。
(1)整体的文件结构
常见二进制文件格式,时常采用 文件头 + 分区 的结构:
file header
section 0
section 1
section 2
section 3
…
section N
1)文件头(file header ):描述了文件的整体信息,常见的字段有魔数、版本号、检验码、文件大小等等。文件头根据文件的具体用途会有额外的字段,比如一张图片,文件头当中就可以含有表示图片尺寸的字段。
2)分区(section):其结构通常是标签+长度+分区数据
tag + length
section data
tag 和 length 合起来是分区头部,后面紧跟着分区的具体数据。
tag:可以是一个整数,也可以是一个字符串。tag 用来标识分区,不同的 tag 表示不同的分区种类,不同的分区种类有各自不同的读取方式。
比如:
#define kPicShapeTag 1
#define kPreivewTag 2
当 tag 为 1 时,就表示是这个分区存放的是图元数据,当为 2 是表示这个分区存放一张预览图。
length:length 是个整数,表示分区数据的具体长度(不包括分区头部)或者