1

编辑:请注意,由于硬盘驱动器实际写入数据的方式,此列表中的任何方案都不能可靠地工作。不要使用它们。只需使用数据库。SQLite 是一个很好的简单的。

在磁盘上存储 UTF-8 字符串元组的最低技术但最可靠的方法是什么?为了可靠性,存储应该是仅附加的。

作为我正在试验的文档存储系统的一部分,我必须将 UTF-8 元组数据存储在磁盘上。显然,对于完整的实施,我想使用 Amazon S3、Project Voldemort 或 CouchDB 之类的东西。

然而,目前,我正在试验,甚至还没有坚定地选择一种编程语言。我一直在使用 CSV,但是当您尝试存储古怪的 unicode 和意外空白(例如垂直制表符)时,CSV 往往会变得脆弱。

我可以使用 XML 或 JSON 进行存储,但它们不能很好地处理仅附加文件。到目前为止,我最好的猜测是一种相当特殊的格式,其中每个字符串前面都有一个 4 字节有符号整数,表示它包含的字节数,整数值 -1 表示这个元组是完整的 - 相当于 CSV 换行符. 头痛的主要来源是必须决定磁盘上整数的字节顺序。

编辑:实际上,这行不通。如果程序在写入字符串时退出,则数据将不可撤销地错位。需要某种带外信令来确保在中止的元组之后可以重新获得对齐。

编辑 2:事实证明,在附加到文本文件时保证原子性是可能的,但解析器非常重要。现在写说解析器。

编辑 3:您可以在http://github.com/MetalBeetle/Fruitbat/tree/master/src/com/metalbeetle/fruitbat/atrio/查看最终结果。

4

2 回答 2

2

我建议制表符分隔每个字段并回车分隔每个记录。

在每个字符串中,替换所有会影响字段并记录解释和呈现的字符。这将包括控制字符(U+0000–U+001F、U+007F–U+009F)、非图形行和段落分隔符(U+2028、U=2029)、方向控制字符(U+202A–U+ 202E)和字节顺序标记(U+FEFF)。

它们应该替换为恒定长度的转义序列。转义序列应以罕见的(对于您的应用程序)字符开头。转义字符本身也应该被转义。

这将允许您轻松附加新记录。它的另一个优点是能够将文件加载到任何电子表格或文字处理程序中进行目视检查和修改,这对于调试目的很有用。

这也很容易编码,因为该文件将是一个有效的 UTF-8 文档,因此可以使用标准的文本读取和写入例程。如果需要,这还允许您轻松转换为 UTF-16BE 或 UTF-16LE,而不会出现复杂情况。

例子:

U+0009 CHARACTER TABULATION becomes ~TB
U+000A LINE FEED            becomes ~LF
U+000D CARRIAGE RETURN      becomes ~CR
U+007E TILDE                becomes ~~~
etc.

制表符作为字段分隔符比逗号更好的原因有几个。逗号在普通文本字符串(如英文文本)中更常见,并且必须更频繁地替换。并且电子表格程序(例如 Microsoft Excel)倾向于更自然地处理制表符分隔的文件。

于 2010-06-30T16:56:10.247 回答
1

主要是在这里大声思考......

真正的低技术是使用(例如)空字节作为分隔符,并且只是“引用”输出中出现的所有空字节,并带有一个额外的空。

也许可以同时使用SCSU

或者可能值得看看gzip格式,如果不使用它,也许可以模仿它:

gzip 文件由一系列“成员”(压缩数据集)组成。

[...]

成员只是在文件中一个接一个地出现,在它们之前、之间或之后没有其他信息。

这些成员中的每一个都可以有一个可选的“文件名”、评论等,我相信你可以继续添加成员。

或者您可以使用在 torrent 文件中使用的bencode 。BSON

另请参阅Wikipedia 的数据序列化格式比较

否则,我认为您在每个字符串之前加上其长度的想法可能是最简单的。

于 2010-06-30T16:03:40.587 回答