在设计用于记录二进制数据的文件格式时,您认为该格式应具有哪些属性?到目前为止,我已经提出了以下要点:
在开头有一些"魔术字节",以便能够识别文件(在我的具体情况下,这也应该有助于区分文件与"遗留"文件)
在开头有一个文件版本号,以便以后可以更改文件格式而不会破坏兼容性
指定所有数据项的字节顺序和大小; 或者:包含一些空间来描述数据的字节顺序/大小(我倾向于前者)
可能为将来可能需要的进一步的每个文件属性保留一些空间?
还有什么方法可以使这种格式更具有前瞻性,并最大限度地减少未来的麻烦?
看看PNG规范.这种格式背后有一些非常好的理由.
此外,确定对您未来格式的重要性:紧凑性,兼容性,允许在其中嵌入其他格式(不同的压缩算法).另一个有趣的例子是Google的协议缓冲区,其中传输数据的大小是王者.
至于字节顺序,我建议你选择一个选项并坚持下去,不允许不同的字节顺序.否则,读写库只会变得更加复杂和缓慢.
我同意这些都是好主意:
一开始的魔术数字.在*nix中非常需要:
用于向后兼容的文件版本号.
字节顺序规范.
但是你的第四个是矫枉过正,因为#2允许你添加字段,只要你更改版本号(并且只要你不需要向前兼容).
可能为将来可能需要的进一步的每个文件属性保留一些空间?
此外,在您的文件征收块结构的想法,在很多其他的答案中表达,似乎不太喜欢比解决一个问题,某些类型的有效载荷的二进制文件的通用要求.
除了以上1-3之外,我还要添加以下内容:
简单的校验和或检测内容完整的其他方式.否则,您无法信任魔术字节或版本号.请注意规范校验和中包含哪些字节.通常,您将在文件中包含尚未进行错误检测的所有字节.
您编写文件的软件版本(包括您拥有的最精细数字,例如内部版本号).你将得到一个错误报告,其中包含一个无法打开它的人的附件,他们在编写文件时没有任何线索,因为那时没有发生错误.但是错误是在编写它的版本中,而不是在试图阅读它的版本中.
在规范中明确指出这是一种二进制格式,即所有字节都允许所有值0-255(幻数除外).
以下是一些可选的:
如果你确实需要向前兼容性,你需要某种方式来表达哪些"块"是"可选的"(比如png),这样你以前的软件版本就可以优雅地跳过它们.
如果您希望"在野外"找到这些文件,您可以考虑嵌入一些线索来查找规范.想象一下在png文件中找到字符串http://www.w3.org/TR/PNG/会有多大帮助.
当然,这完全取决于格式的目的.
一种灵活的方法是将整个文件构造为TLV(Tag-Length-Value)三元组.例如,使您的文件由记录组成,每个记录以4字节标题开头:
1 byte = record type 3 bytes = record length followed by record content
关于字节顺序,如果在文件中存储字节顺序指示符,则所有应用程序都必须支持所有字节顺序格式.另一方面,如果为文件指定特定的字节序,则只有具有不匹配的endiannes的平台上的应用程序才能执行其他工作,并且可以在编译时决定(使用条件编译).
另一点,取自.xz文件规范(http://tukaani.org/xz/xz-file-format.txt):前几个字节之一应该是非字符,"以防止应用程序错误检测文件作为文本文件." 请注意编辑器和其他工具通常会检查多少个头字节,但在前四个或八个字节中使用非二进制字节似乎很有用.