首先,文件将由记录组成。一个GUID字段和一个JSON / YAML / XML数据包字段。我不确定要使用什么作为分隔符。逗号、制表符或换行似乎太脆弱了。Excel做了什么?或者是XML之前的OpenOffice格式?应该使用ASCII字符0或1。不确定从哪里开始。有关此主题的任何文章或书籍吗?
这个文件格式可能会后续扩展以包括“头部节”。
注意:起初我将在.NET中工作,但我希望该格式易于移植。
更新: “数据包”的处理可能很慢,但是文件格式内的导航不能慢。所以我认为XML不可行。
byte[]
。通常情况下,在.NET工作中,我会推荐protobuf-net(但作为作者,我有点偏见),但是,如果您打算以后使用其他语言,最好使用Jon的dotnet-protobufs;这样可以在各个平台上获得熟悉的API(而protobuf-net使用.NET习惯用语)。我会尝试提供一些有关创建便携式二进制文件格式的通用提示。
请注意,发明二进制文件格式意味着要记录其中的位应如何排列以及它们的含义。这不是编写代码,而是文档编写。
现在是提示:
决定如何处理字节序(endianess)。一个好且简单的方法是确定一次并永久使用。如果在常见的个人电脑上(即x86),选择小端字节序以避免转换(提高性能)。
创建文件头(header)。是的,始终具有文件头是一个好主意。文件的前几个字节应该能够告诉你正在处理什么格式。
最后,添加数据。现在,数据的格式将是特定的,并且它总是基于您确切需求的某些数据结构。基本上,数据将存储在某些数据结构的二进制图像中。数据结构是您需要想出的。
如果您需要通过某种索引来随机访问数据,则B-Trees是最好的选择,而如果您只需编写大量数字,然后全部读取它们,“数组”即可完成。
此外,您可能会使用类型-长度-值(TLV)概念以实现向前兼容性。
然而,如果您的主要关注点是可移植性,我建议不要使用二进制格式。 XML 的设计目的正是为了解决可移植性和互操作性问题。它作为文件格式冗长而笨重,但这是您为解决这些问题所做的权衡。 如果不考虑人类可读的格式,Marc's answer 是可行的方法。没有必要重新发明可移植性轮子!
struct Format
{
struct Header // 1
{
byte a;
bool b1, b2, b3, b4, b5, b6, b7, b8;
string name;
}
struct Container // 1...*
{
MyTypeEnum Type;
byte[] data;
}
}
enum MyTypeEnum
{
Sound,
Video,
Image
}
那么我将拥有一个顺序文件,其中包含:
字节 // a
字节 // b
整数 // 名称大小
字符数组[] // 名称(其大小在上面指定,记住在.NET中一个字符是16位)
整数 // MyTypeEnum类型
整数 // 数据大小
字节数组[] // 数据(其大小在上面指定)
然后,您可以重复最后三行任意次数。
要进行读取,您可以使用BinaryReader
,它支持读取字节、整数和一系列字节。还有一个BinaryWriter
。
此外,请记住,Microsoft .NET(因此在Windows / Intel计算机上)是小端字节序。因此,BinaryReader
和BinaryWriter
也是如此。
这取决于你将要写入二进制文件的数据类型以及二进制文件的用途。它们是类对象还是记录数据?如果是记录数据,我建议将其放入XML格式中。这样,您可以包含模式验证以验证文件符合您的标准。在Java和.NET中都有工具可导入和导出数据到/从XML格式。