考虑到以下几点,我们应该在什么时候使用yaml而不是json,反之亦然?
- 性能(编码/解码时间)
- 内存消耗
- 表达清晰
- 图书馆可用性、易用性(我更喜欢C)
我计划在我们的嵌入式系统中使用这两个文件中的一个来存储配置文件。
相关:
我应该使用yaml或json来存储Perl数据吗?
- 请注意,JSON可以被视为yaml:en.wikipedia.org/wiki/json yaml的一个子集。
- @查尔斯,是的,但它们有一些微妙的区别:ajaxian.com/archives/json yaml its getting closer‌&8203;-to truth
- 你为什么说"喜欢C?"
- 由于Yaml(近似)是JSON的超集,因此如果不假设您是否将使用这种表达性,就无法回答性能问题。如果您不需要它:YAML解析器在读取JSON方面有多快?如果您确实需要:当您允许相同想法的JSON表示可能更长时,JSON解析器会慢多少?
- @开玩笑的我想"我更喜欢C图书馆"(例如Libyaml)
- 不提倡,但我见过一些非常简单的Lua数据格式。
- yaml文档可能很复杂,很难阅读。用山药可以进行"十亿笑"攻击。另一方面,复杂对象、图形和其他结构可以在yaml中高效地序列化。对于交换格式和简单结构,首选JSON。对于复杂的对象序列化或语法定义,可能首选yaml。
- yaml-你们都用这种格式做了缩进错误。
从技术上讲,yaml是json的超集。这意味着,至少在理论上,yaml解析器可以理解JSON,但不一定是另一种方式。
参见官方规范,标题为"YAML:与JSON的关系"一节。
一般来说,我喜欢一些在JSON中不可用的关于yaml的东西。
- 正如@jdupont所指出的,yaml在视觉上更容易看到。事实上,yaml主页本身就是有效的yaml,但是对于人来说很容易阅读。
- yaml能够使用"锚"引用yaml文件中的其他项,因此它可以像在mysql数据库中那样处理关系信息。
- yaml对于在yaml文件中嵌入其他序列化格式(如json或xml)更为健壮。
实际上,这两个点对于您或我所做的事情都不太重要,但从长远来看,我认为YAML将是一种更健壮和更可行的数据序列化格式。
目前,Ajax和其他Web技术倾向于使用JSON。yaml目前更多地用于离线数据处理。例如,默认情况下,它包含在基于C的Opencv计算机视觉包中,而JSON则不包括在内。
您将找到JSON和YAML的C库。Yaml的图书馆往往比较新,但我过去对它们没什么问题。参见Yaml CPP示例。
- JSON不是一个子集(尽管它很接近),当您遇到它们时,不兼容性会让您恼火。JSON库通常更快…(stackoverflow.com/questions/2451732/…)。yaml的支持者会坚持认为它是一个子集。如果需要考虑可读性,请使用yaml。如果需要考虑互操作性和速度,请使用JSON。
- yaml是特定形式JSON语法的超集。也就是说,如果以与yaml兼容的方式使用JSON,那么它是一个适当的子集。正如Pierr上面所评论的,这些规范[旨在兼容性](ajaxian.com/archives/json yaml its getting cl‌&8203;oser to truth)。
- 此外,Yaml还支持方便的评论。
- JSON不支持评论吗?JSON不是一种更特殊的对象文字表示形式吗?
- @Aaron不是JSON"支持评论"吗?-没有。
- @Erikaronesty JSON接近于yaml 1.1的一个子集,但由于yaml 1.2,它现在是一个真正的子集。yaml 1.2主要是用来消除两种规格之间最后几个不兼容之处。
- 根据yaml 1.2规范:"本次修订的主要目标是使yaml作为官方子集符合JSON。"
- json是yaml 1.2的一个子集,假定这个cstring不会在yaml中解析:" "abc":"xyz""
- @埃文本1。JSON不是yaml的严格子集。JSON允许重复的键。山药没有。如果有人决定反序列化到一个多映射中(看到了它,就在那里),那么yaml就是不起作用。2。我敢说,bug更可能出现在更复杂的yaml解析器中。
差异:
yaml的可读性比json高,这取决于您如何使用它。
JSON通常更快,而且可能仍然可以与更多的系统进行互操作。
很快就可以编写一个"足够好"的JSON解析器。
重复的键(可能是有效的JSON)绝对是无效的yaml。
Yaml有很多特性,包括注释和关系锚。因此,yaml语法相当复杂,很难理解。
可以在yaml:{a: &b [*b]}中编写递归结构,它将在某些转换器中无限循环。即使有了循环检测,"山药炸弹"仍然是可能的(见XML炸弹)。
因为没有引用,所以不可能在JSON中用对象引用序列化复杂的结构。因此,yaml序列化可以更有效。
在某些编码环境中,使用yaml可以让攻击者执行任意代码。
观察:
由于使用缩进而不是括号语法来指示级别,Python程序员通常是Yaml的忠实粉丝。
许多程序员认为"意义"对缩进的附加是一个糟糕的选择。
如果数据格式将离开应用程序的环境、在UI中解析或在消息传递层中发送,那么JSON可能是更好的选择。
yaml可以直接用于语法定义之类的复杂任务,通常比发明一种新语言更好。
- 你能把第三点扩展一下吗?我以为是的。
- 它是。yaml 1.2的全部目的是解决一些兼容性差异,使JSON成为一个严格的子集。如果您认为规范没有达到它的目的,Erik,请指出一个有效JSON的例子,它违反了yaml规范和/或破坏了一个经过验证的1.2兼容的yaml解析器。
- @Yaml规范说,可能存在无效的JSON文件。但它不太可能真正使用。"JSON的rfc4627要求映射键"应该"是唯一的,而yaml则坚持它们"必须"是唯一的。因此,从技术上讲,yaml符合JSON规范,选择将重复项视为错误。实际上,由于JSON对这种重复的语义是沉默的,所以唯一可移植的JSON文件是那些具有唯一键的文件,因此它们是有效的YAML文件。"-yaml.org/spec/1.2/spec.html id2759572
- 公平点。(虽然在实践中不太可能出现,但这不是问题。)谢谢。
- 对缩进的使用进行评论;嗯,我认为这可能需要习惯,并不是每个人都喜欢。例如,我是一个.NET用户。我正在查看travis.yml文件,想知道为什么会有问题。我发现我有一张账单,上面写着"不可能"。不是每个人都习惯于空间/制表符/新行首选项导致的爆炸。
- 完全不允许使用制表符作为缩进字符。imho,这在所有语言中都是很好的编码风格-有或没有语法缩进。
- 关于标签和空格的问题:medium.com/@hoffa/…
- 观察点2"许多程序员"——这是一种没有来源的"黄鼠狼"语言。找到一个来源,并作出一个可量化的声明或删除它。
- @我个人喜欢Python和山药,每天都用。我倾向于将yaml用于人们必须经常编辑的内容,将json用于人们"可能"需要查看的内容。我一直受到C++程序员的有效批评,他们发现缩进会让人困惑。尤其是在有多个级别或更长的功能块的情况下。当然。。。好的可测试代码没有这些东西,所以通常不是问题。这是我个人的观察,但是任何一个偶然的谷歌搜索都会产生很多结果…所以验证起来很简单。
- @sfeley这个有效的json不会解析为yaml:" "abc":"xyz""
绕过深奥理论
这就回答了标题,而不是像我一样从谷歌的搜索结果中读取标题的细节,所以我觉得有必要从Web开发人员的角度进行解释。
yaml使用空白缩进,这是Python开发人员熟悉的领域。
Javascript开发人员喜欢JSON,因为它是Javascript的一个子集,可以在Javascript中直接解释和编写,并使用一种简单的方法声明JSON,在使用没有空格的典型变量名时,不需要在键中使用双引号。
对于yaml和json,有大量的解析器在所有语言中都能很好地工作。
在许多情况下,Yaml的空白格式更容易查看,因为格式化需要更人性化的方法。
如果编辑器中没有可见的空白或缩进行指示器,那么Yaml的空白虽然更紧凑、更易于查看,但却很难手动编辑。
JSON的序列化和反序列化速度要快得多,因为要检查的特性比Yaml少得多,这使得处理JSON的代码更小、更轻。
一个常见的误解是Yaml需要的标点符号更少,而且比JSON更紧凑,但这完全是错误的。空白是不可见的,所以看起来字符较少,但是如果您计算实际的空白,这是必要的,以便正确解释yaml和适当的缩进,您会发现yaml实际上需要比json更多的字符。JSON不使用空白来表示层次结构或分组,并且可以很容易地扁平化,删除不必要的空白以实现更紧凑的传输。
房间里的大象:互联网本身
显然,javascript在Web上占据了巨大的优势,而javascript开发人员更喜欢将JSON作为数据格式,并与流行的Web API一起使用,因此在一般意义上,在进行Web编程时,使用yaml比json更难争论,因为在团队环境中,您可能会被淘汰。事实上,大多数Web程序员甚至不知道yaml的存在,更不用说考虑使用它了。
如果您正在进行任何Web编程,JSON是默认的方式,因为在使用JavaScript时不需要转换步骤,因此在这种情况下,您必须想出一个更好的参数来使用YAML而不是JSON。
- 我不同意Python开发人员更喜欢yaml。pythons dict是basically json,dict列表也基本上是json。python有内置的json lib。另一方面,我是一个python开发人员,我更喜欢json(我认识的大多数python开发人员都喜欢json)。
- @我更新了第一点。
- 当你谈到"翻译步骤"时,很有必要区分心理翻译和机械翻译。熟悉JavaScript的人类读者同样熟悉JSON。对于机器来说,javascript和yaml之间的差别是微乎其微的;在实践中,很少有人会因为注入攻击而使用eval(jsonString)。当必须解析JSON和YAML时,JSON作为本机JavaScript的优势就丧失了。
- @toolbear可以安全地使用json.parse(jsonString),而不是eval(jsonString)
- 根据我的经验,JSON的简单性/简约性优于YAML的一个原因是它必须处理解析库之间的互操作,特别是跨平台的互操作。只需比较JSON和YAML规范,很明显,YAML实现必然会有更多的bug、缺失的特性或对规范的不同解释;当从不同的堆栈生成和使用YAML时,每一个都是一个潜在的互操作错误。JSON的简单性和它对它的更多关注相结合,导致了更好的互操作性。这符合我的经验。
- @杰森·贝林,这就是我的观点。JSON.parse是一个解析器。这使得JSON与Yaml在机器环境中存在"翻译步骤"的基础相同。
- @toolbear同意,但我的意思是您可以在javascript及其实际的javascript中声明JSON,因此在这方面没有翻译步骤。如果您正在分析传入的数据,那么这是一个不同的情况,但在这种情况下,您必须分析任何属于数据结构的内容,因此这是对这一点的一个清洗。
- 有一件事让我很困扰,那就是很容易被混淆和搞错,因为缩进或不缩进可能意味着它是嵌套的或在同一级别上的,而且如果没有引导规则,也很容易出错。就像隐藏的OOPS,这真的不是一个简单的类型场景,没有人在编辑yaml时说。JSON从未有过这样的问题。
- @杰森·贝林。你几乎会想知道为什么Yaml会有空格。我第一次"在海洋中浸泡"的Yaml导致了一个坏应用程序…都是因为空间。你可能认为使用缩进而不是非打印字符会更有意义!(也就是说,他们到底为什么不选择'。'而不是'?)要理解yaml,你必须按照规格操作。了解JSON并不需要。(我去过前者,而不是后者)。对我来说,这表示一种不是真正"人类可读"的格式。
- @这是我的经验。我的老板强迫我们在JSON上使用yaml,这使得编辑和摄取东西变得不必要。我写这篇文章是因为我希望投票结果能证明我的正确性。
- 一篇深思熟虑的文章。是的,房间里那只大象正坐在沙发上吃着一袋埃多克斯(0)
- 山药的可读性更强。JSON更人性化。
- @作为一个随机的IT人员,霍诺德穆勒经常破解东西,而不是从零开始创建。人的可写性就是人的可读性,在多个IDE和平台上人的可读性,而不需要考虑空白是如何呈现的,这就是黄金。对我来说,这使得人们天生对空白的可读性成为一种洗礼。我又开始斜视了,废话。
- yaml中的标签出现问题意味着(a)没有读取错误消息,以及(b)有一个不突出显示标签的编辑器。这两个问题都很容易解决,所以我不理解这些抱怨。
这个问题已经6岁了,但奇怪的是,没有一个答案能真正解决这四个问题(速度、记忆、表达能力、可移植性)。
速度
显然,这是依赖于实现的,但是由于JSON被广泛使用,并且易于实现,所以它倾向于获得更大的本机支持,从而提高了速度。考虑到Yaml做了JSON所做的一切,再加上一卡车的工作量,在这两者的任何类似实现中,JSON One都将更快。
但是,考虑到yaml文件可能比它的JSON对应文件稍小(由于"和,字符较少),在特殊情况下,高度优化的yaml解析器可能更快。
记忆
基本上相同的论点也适用。如果它们表示相同的数据结构,那么很难理解为什么yaml解析器比JSON解析器内存效率更高。
表现力
正如其他人所指出的,python程序员倾向于选择yaml、javascript程序员而不是json。我将进行以下观察:
- 很容易记住JSON的整个语法,因此对于理解任何JSON文件的含义非常有信心。山药是任何人都无法真正理解的。微妙和边缘情况的数量是极端的。
- 因为很少有解析器实现整个规范,所以更难确定给定上下文中给定表达式的含义。
- 实际上,JSON中缺乏评论是一种真正的痛苦。
便携性
很难想象没有JSON库的现代语言。也很难想象一个JSON解析器实现任何低于完整规范的东西。Yaml有广泛的支持,但比JSON不那么普遍,并且每个解析器实现不同的子集。因此,yaml文件的互操作性比您想象的要差。
总结
JSON是性能(如果相关)和互操作性的赢家。山药更适合人类保存的文件。HJSON是一个不错的折衷方案,尽管它的可移植性大大降低。JSON5是一个更合理的折衷方案,具有定义良好的语法。
- 事实上,我认为Yaml更小是因为无形的人物欺骗了我。看不见=>不在那里,实际上不在。如果您计算必须存在的不可见字符数,特别是当yaml得到更大的嵌套时,它很快就会超过json。我只是觉得这很有趣,因为人类可读的部分愚弄了我们大多数人的想法,直到我真的考虑它,因为你可以扁平JSON和YAML,不是那么多。我还发现yaml很难手工编辑,而不是阅读,只是在需要打开编辑器指南时进行编辑,有时很容易弄错嵌套项。
- 我觉得这里没有一个答案明确地说明这一点:"对于设置/配置文件,yaml更好(因为每个人都提到了上述原因)。对于机器/机器互操作,使用json"。换句话说:如果你的目标受众是人,那么yaml就更好了。如果目标是另一个程序(但您仍然希望数据是人类可读的),请使用JSON。
- 这是真的,但问题列出了一些非常具体的参数,关于他们希望如何比较这两者。就我个人而言,我不会用山药做任何事。我要么使用JSON来实现互操作性,要么使用JSON6来实现人员维护。
我发现yaml在眼睛上更容易看到:更少的括号,"等等。尽管yaml中的制表符很烦人…但有人能理解。
在性能/资源方面,我不希望两者之间有很大的差异。
此外,我们讨论的是配置文件,所以我不希望有高频率的编码/解码活动,不是吗?
- 是的,性能可能不是问题。
- 我想知道你说的标签烦恼是什么意思。我认为Yaml中不允许使用制表符,我个人认为这在任何源文件中都是一个好主意。
- @Poolie:jldupont可能指的是yaml中语法意义重大的前导空格。
- 好的,但它们不是标签。
如果您不需要Yaml拥有的任何特性,而JSON不需要,那么我更喜欢JSON,因为它非常简单,并且得到广泛的支持(有许多语言的库)。山药更复杂,支持度也更低。我不认为解析速度或内存使用会有很大的不同,也许对程序性能的影响不大。
- 山药在哪方面更复杂?
- 例如,yaml支持锚,如另一个答案所述。还有其他功能,例如可扩展数据类型。这使得解析更加复杂,并解释了为什么Yaml具有更大的规范。根据解析器的实现,它可能会损害性能(请看这个问题:stackoverflow.com/questions/2451732/…)。
- 如果复杂性让你有能力实现更大的整体简单性,那么复杂性比简单性更好。根据数据模型的复杂性,这当然是正确的。
- 我可能晚了一点,但Yaml可以添加注释,而JSON不能。对我来说,在规范文档方面这是一个很大的帮助。
- @意外事故。我认为,人们在这里就差异提出问题,这是一个确定的迹象,Yaml并不是那么容易。我从来没有问过关于JSON的问题(除了"为什么我不能在里面写评论?")
- 这是我一直在寻找的答案,去推翻它。我发现任何一个有理解力的人都很难有任何理由使用山药而不是评论。这是wayyy更复杂,为什么让人们学习另一种不简单和明显的语法,而且显然对开发人员来说更困难?谁真的想要锚定在他们的配置文件中?只需使用json,noobs。
Git和Yaml
其他答案都很好。先读这些。但有时我会添加一个使用yaml的其他原因:git。
越来越多的编程项目使用Git存储库进行分发和归档。而且,虽然Git repo的历史可以同样存储JSON和YAML文件,但用于跟踪和显示文件更改的"diff"方法是面向行的。由于yaml必须是面向行的,所以yaml文件中的任何小更改都很容易被人看到。
当然,通过对字符串/键进行排序并添加缩进,可以使JSON文件"漂亮"。但这不是默认值,我很懒惰。
就个人而言,我通常使用JSON进行系统到系统的交互。我经常将yaml用于配置文件、静态文件和跟踪文件。(我通常也避免添加yaml关系锚。生命短暂,无法追寻循环。)
另外,如果速度和空间真的是一个问题,我也不使用。你可能想看看BSON。
从技术上讲,yaml提供了比json更多的功能(yaml v1.2是json的超集):
- 评论
锚定和继承-3个相同项的示例:
1 2 3 4 5 6 7
| item1: &anchor_name
name: Test
title: Test title
item2: *anchor_name
item3:
<<: *anchor_name
# You may add extra stuff. |
- …
大多数时候人们不会使用这些额外的特性,主要的区别是yaml使用缩进,而json使用括号。这使得Yaml更简洁易读(对于受过训练的人来说)。
选择哪一个?
- yaml额外的特性和简洁的符号使它成为配置文件(非用户提供的文件)的一个很好的选择。
- JSON有限的特性、广泛的支持和更快的解析使它成为互操作性和用户提供数据的一个很好的选择。
有时你不必为一个决定另一个。
例如,在Go中,您可以同时拥有这两种功能:
1 2 3 4
| type Person struct {
Name string `json:"name" yaml:"name"`
Age int `json:"age" yaml:"age"`
} |
由于这个问题在搜索yaml和json时具有突出的特点,所以值得注意的是,很少有人引用这两者之间的区别:许可证。JSON声称拥有JSON用户必须遵守的许可证(包括法律上含糊不清的"应善用,而不是邪恶")。Yaml没有这种许可证申请,这可能是一个重要的区别(对你的律师,如果不是对你)。
- 我不使用JSON,我使用与JSON完全相同的JSON而不调用它JSON。我叫它PS-OFF。你要控告我使用{"": #, [] }吗????
- 在"大数据"和"唯一可读"点上,您的意思是什么?JSON是一种数据格式,抽象概念有这两个限制吗?
- @Jo&227;ofarias让我们假设您有1GB JSON文件和1GB CSV文件,并且您有256MB的内存。您可以一行一行地处理csv文件,使用json是不容易实现的。与解析JSON相比,逐行解析yaml文件可能仍然更容易。
我发现Yaml和JSON都非常有效。当一种语言在我身上被使用而另一种语言在我身上被使用时,唯一能真正支配的两件事是一件事,那就是语言最常用的东西。例如,如果我使用Java,JavaScript,我将使用JSON。对于Java,我将使用他们自己的对象,这些对象几乎是JSON,但缺少一些特性,如果需要的话,首先将其转换成JSON,或者在JSON中转换为JSON。我这样做是因为在Java中这是一个常见的事情,让其他Java开发人员更容易修改我的代码。第二件事是我是否使用它来让程序记住属性,或者如果程序正在接收配置文件形式的指令,在这种情况下,我将使用yaml,因为它很容易被人读取,有漂亮的语法,并且很容易修改,即使你不知道yaml是如何工作的。然后,程序将读取它并将其转换为JSON,或者该语言首选的任何语言。最后,老实说,这无关紧要。任何有经验的程序员都很容易阅读JSON和YAML。