授权协议:MIT
翻译:gemini-2.0-flash
,有初步校对。
致 CSV 格式的一封情书
或者为什么那些声称 CSV 已死的人是错误的
大约每个月都会出现一篇新的博客文章,宣称 CSV 已经接近消亡,取而代之的是一些“明显更优越”的格式(parquet、换行符分隔的 JSON、MessagePack 记录等)。 遗憾的是,这些文章通常提供非常狭隘和有偏见的比较,并且常常未能理解是什么让 CSV 成为看似无法扼杀的数据序列化主要格式。
因此,我打算通过本文,向这种数据格式写一封情书,它经常因错误的原因受到批评,尤其是在以某种方式认为“讨厌”它很“酷”的时候。 我的目的远非说 CSV 是万能的,而是想阐明该格式的一些有时被忽视的优点。
1. CSV 非常简单
CSV 的规范体现在其标题中:“逗号分隔的值”。 好吧,这是一个谎言,但仍然,该规范可以浓缩到一条推文中,并且可以在几秒钟内向任何人解释:逗号分隔值,换行符分隔行。 现在引用包含逗号和换行符的值,双倍引用你的引号,就是这样。 这非常简单,你甚至可能在学习如何编程时,在不知道它已经存在的情况下自己发明它。
当然,这并不意味着你不应该使用专用的 CSV 解析器/写入器,因为你会搞砸一些事情。
2. CSV 是一种集体思想
没有人拥有 CSV。 它没有真正的规范(是的,我知道有争议的事后 RFC 4180),只是一套每个人都隐式同意遵守的规则。 它现在是,并且将永远是,一个开放和自由的集体思想。
3. CSV 是文本
像 JSON、YAML 或 XML 一样,CSV 只是纯文本,你可以自由地以任何你喜欢的方式进行编码。 CSV 不是二进制格式,可以用任何文本编辑器打开,并且不需要任何专门的程序来读取。 这意味着,通过扩展,它可以被人类直接读取和编辑。
4. CSV 是可流式的
CSV 可以非常容易地逐行读取,而不需要比容纳单行所需更多的内存。 这也意味着,任何人都能够编写的简单程序都能够读取千兆字节的 CSV 数据,而只需要一些千字节的 RAM。
相比之下,面向列的数据格式(如 parquet)无法逐行流式传输文件,而无需你在文件中到处跳转或巧妙地缓冲内存,这样你就不会降低读取性能。
当然,如果你只对特定列感兴趣,CSV 会很糟糕,因为你确实需要读取整行才能访问你感兴趣的部分。
面向列的数据格式当然非常适合 R、pandas 等数据框的思维方式。 但是,来自这组实践的 CSV 批评者往往只关心期望所有内容都适合内存的用例。
5. CSV 可以追加
在 CSV 文件的末尾添加新行非常简单,而且这样做非常有效。 只需以追加模式 (a+
) 打开文件即可。
同样,面向列的数据格式无法做到这一点,或者至少不能以直接的方式做到这一点。 实际上,它们可以被视为磁盘上的数据框,并且与数据框一样,添加列非常有效,而添加新行则不然。
6. CSV 是动态类型的
请不要逃离。 让我解释一下为什么这有时是一件好事。 有时在处理数据时,你可能希望在解析序列化数据时具有一定的灵活性,尤其是在跨编程语言时。
例如,考虑 JavaScript,它无法表示 64 位整数。 或者哪些语言、框架和库将什么视为空值(不要让我开始讨论 pandas 和空值)。 CSV 允许你随意解析值,并且实际上是动态类型的。 但这既是优势,也可能在你不小心的情况下成为潜在的陷阱。
另请注意,但这可能很难用高级语言(如 python 和 JavaScript)做到,你根本不需要解码文本来处理 CSV 单元格值,并且你可以直接在文本的二进制表示上工作以提高性能。
7. CSV 是简洁的
只在文件开头编写一次标头意味着格式的形式重复量自然非常低。 考虑 JSON 中的对象列表或 XML 中的等效列表,你将很快看到到处重复键的成本。 这并不意味着 JSON 和 XML 不会很好地压缩,但很少有格式能表现出这种自然简洁的程度。
更重要的是,字符串通常已经以最佳方式表示,并且格式本身的开销(此处和彼处的某些逗号和引号)保持在最低限度。 当然,静态类型的数字可以更简洁地表示,但你也不会在那里节省一个数量级。
8. 反向 CSV 仍然是有效的 CSV
这个并非每个人都能意识到,但是一个反向的(逐字节)CSV 文件,仍然是有效的 CSV。 这仅仅是因为通过加倍引用来转义引号的绝妙想法才成为可能,这意味着转义是回文。 如果 CSV 使用基于反斜杠的转义方案,这将不起作用,这在表示字符串文字时最常见。
但是你为什么要关心呢? 好吧,这意味着你可以非常高效且非常容易地读取 CSV 文件的最后几行。 只需将文件的字节按相反的顺序输入到 CSV 解析器,然后反转生成的行及其单元格的字节,你就完成了(也许先读取标头行)。
这意味着你可以很好地使用 CSV 输出作为有效恢复中止过程的一种方式。 实际上,你可以以恒定的时间读取和解析 CSV 文件的最后几行,因为你不需要读取整个文件,而只需要将自己定位在文件末尾以反向缓冲字节并将它们输入到解析器。
9. Excel 讨厌 CSV
这显然意味着 CSV 一定做对了什么。
签名:xan, CSV 魔术师