CSV:好的、坏的和丑陋的

2020-11-08 09:29:01

CSV是一种相对流行的数据格式,作为一种提供中型数据集输出的格式似乎特别常见。我的日常工作涉及处理大量这种类型的数据集,因此我对CSV形成了一套强有力的观点,这些观点都记录在这里。

CSV的一个特点通常被认为是一个很大的优势,那就是它是一种极其简单的文件格式。然而,这可能会产生误导。

它们支持流处理,你不需要在内存中保存整个文件来处理它。

它们的空间效率相对较高,CSV格式本身对数据本身的大小施加了相对较低的开销(具体地说,每条记录不会重复每列的名称)。

解析器在每种流行的编程语言中都广泛可用,而且许多小数据处理工具(例如Excel)本身也支持解析器。

CSV有类似的格式,即制表符分隔值和竖线分隔值。这些格式通常与CSV半互换使用,但支持程度稍差一些,如果您解析的东西需要错误的分隔符,您将得到无声的错误。

CSV没有类型,所有内容都是字符串。这意味着没有本机Sequencetype,也没有与空字符串不同的空性概念。

大多数流行的CSV库都没有得到很好的优化,这使得CSV的解析速度比需要的慢得多。

似乎很多人在生产和消费CSV时并没有使用真正的CSV库。这是因为CSV的格式非常简单,很多人没有意识到它有转义和引用的规则。许多人似乎使用file.write(";,";.Join(Field))生成CSV,当其中一个字段包含引号或逗号时,会产生无法解析的混乱。

这可能会产生灾难性的混乱,因为没有重新同步的机制。考虑以下问题:

许多CSV解析器将生成类似以下内容的内容,这是根据RFC4180进行的正确解析:

然而,有些引号也可能会产生以下结果,如果你将引号视为原文或天真的逗号分隔符,你会得到这样的结果:

或者,如果您隐式结束一行末尾的所有引号,甚至可以执行以下操作:

这使得解析CSV文件成为一种令人担忧的体验。事实上,大多数CSV库都包含关于如何处理这类情况的各种启发式方法,这使得结果在不同语言之间不一致。

我使用从几十个不同系统生成的CSV的经验是,引用、转义和其他我强调为“丑陋”的解析错误是一个大问题。不幸的是,据我所知,目前还没有一种支持流处理、存储开销低且得到工具广泛支持的竞争格式。这样的格式将是非常有价值的…。IFit被广泛采用。在某一轴上有几种成功的替代方案:

以行分隔的JSON可以工作,但会带来很大的开销(每条记录都重复使用字段名),并且在非编程环境中不受很好的支持。

拼图文件运行良好,但流媒体稍微复杂一些(您需要能够查找到文件末尾才能读取元数据,然后才能对内容进行流媒体传输),并且没有得到广泛的支持。

Excel文件不能很好地支持流,在编程环境中的支持也相对较差。

归根结底,没有一种格式可以在保留其优点的同时纠正所有CSV缺陷。