3个不稳定版本
0.2.0 | 2020年12月4日 |
---|---|
0.1.1 | 2020年11月28日 |
0.1.0 | 2020年11月28日 |
#47 在 #解析器
23KB
418 行
c0sv
这是一个二进制CSV格式。非常简单,由ASCII控制字符分隔。使用SOH(标题开始)、STX(文本开始)、ETX(文本结束)、ESC(转义)、US(单元分隔符)和RS(记录分隔符)。
流用以下伪EBNF表示(其中*代表任意单个字节)
stream = [header], STX, records, ETX
header = SOH, units
units = unit, { US, unit}
unit = { (* - control) | (ESC, *) }
control = SOH | STX | ETX | ESC | US | RS
records = units, { RS, units}
这主要是一个简单的实验,看看是否有可能创建一个非常类似CSV的格式,使用这些ASCII控制字符进行分隔(特别是使用控制字符按照它们被期望的方式使用)。这可能不是特别有用,因为CSV的唯一真正目的是交换,其中手动可读性和/或可写性很重要。如果你想要好的二进制灵活性,你可能会更好地使用像bincode或messagepack这样的良好二进制格式。
尽管如此,这确实有一些方便的方面,比如它相当容易流式传输,允许在只需要一次内存的情况下处理记录。以解析速度较慢为代价,这种格式比大多数其他二进制格式略小,因为没有长度前缀。
优点
相对于CSV
- 标题是显式分隔的,因此永远不会猜测第一行是否是标题。
- 只有一种转义方法,因此不需要对如何处理字段中的特殊字符(如逗号或换行符)产生混淆。在这种情况下,解析也更简单,因为CSV解析器通常会天真地尝试处理交织的换行符。
- 文档的结尾也是显式分隔的,因此可以将带有标题的多个文档连接到同一流中,而不会丢失任何内容。
缺点
- 控制字符不是真正可打印的,因此这种格式不能很容易地用文本编辑器编辑。
- 因为字段和记录是用分隔符分隔的,所以至少有一个字段和一个记录。由以下代码表示的文档
[STX][ETX]
是一个只有一个记录的文档,该记录由一个空字段组成。这意味着不可能表示没有任何字段的记录(它将是一个空字段,而不是没有字段),或者没有任何记录的文档(它将是一个只有一个空字段的记录)。
最后一个问题可能可以通过使用记录分隔符和单元分隔符作为前缀而不是分隔符来解决,但这不太有趣,并且不符合控制字符的语义。它还会使文档大小每条记录增加一个额外的字节。
依赖关系
~1MB
~22K SLoC