UTF-8和UTF-8与BOM有什么不同?哪个更好?


当前回答

UTF-8和没有BOM的UTF-8有什么不同?

简单回答:在UTF-8中,BOM编码为文件开头的字节EF BB BF。

长一点的回答:

最初,预计Unicode将以UTF-16/UCS-2编码。BOM是为这种编码形式设计的。当您有2字节的代码单元时,有必要指出这两个字节的顺序,这样做的一个常见惯例是在数据的开头包含字符U+FEFF作为“字节顺序标记”。字符U+FFFE是永久未分配的,因此可以使用它来检测错误的字节顺序。

不管平台字节顺序如何,UTF-8都具有相同的字节顺序,因此不需要字节顺序标记。然而,它可能出现在从UTF-16转换为UTF-8的数据中(作为字节序列EF BB FF),或者作为表示数据为UTF-8的“签名”。

哪个更好?

没有。正如Martin Cote回答的那样,Unicode标准并不推荐这样做。它会导致非bom识别软件出现问题。

检测文件是否为UTF-8的更好方法是执行有效性检查。UTF-8对哪些字节序列是有效的有严格的规则,因此假阳性的概率可以忽略不计。如果一个字节序列看起来像UTF-8,那么它可能就是。

其他回答

一个实际的区别是,如果你为Mac OS X编写一个shell脚本,并将其保存为普通的UTF-8,你将得到响应:

#!/bin/bash: No such file or directory

在shebang行指定您希望使用哪个shell的响应中:

#!/bin/bash

如果你保存为UTF-8,没有BOM(说在BBEdit),一切都会很好。

没有BOM的UTF-8没有BOM,这并不意味着它比有BOM的UTF-8更好,除非文件的消费者需要知道(或者从知道中受益)文件是否是UTF-8编码的。

BOM通常用于确定编码的字节序,这对于大多数用例来说是不需要的。

此外,对于那些不了解或不关心BOM的消费者来说,BOM可能是不必要的噪音/痛苦,并可能导致用户困惑。

以下是我使用Visual Studio、Sourcetree和Bitbucket拉请求的经验,这给了我一些问题:

因此,在审查拉取请求时,带有签名的BOM将在每个文件上包含一个红点字符(这可能非常烦人)。

如果你把鼠标停在上面,它会显示一个像“ufeff”这样的字符,但事实证明Sourcetree不显示这些类型的字节标记,所以它很可能会在你的拉请求中结束,这应该是可以的,因为这是Visual Studio 2017现在编码新文件的方式,所以也许Bitbucket应该忽略这个或让它以另一种方式显示,更多信息在这里:

红点标记BitBucket差异视图

其他优秀的回答已经回答过了

UTF-8和BOM-ed的UTF-8之间没有官方的区别 一个BOM-ed的UTF-8字符串将以以下三个字节开始。Ef bb bf 如果存在这些字节,在从文件/流中提取字符串时必须忽略。

但是,作为附加信息,UTF-8的BOM可以很好地“嗅出”字符串是否以UTF-8编码……或者它可以是任何其他编码的合法字符串…

例如,数据[EF BB BF 41 42 43]可以是:

合法的ISO-8859-1字符串“ABC” 合法的UTF-8字符串“ABC”

因此,尽管通过查看第一个字节来识别文件内容的编码很酷,但您不应该依赖于此,如上面的示例所示

编码应该是已知的,而不是推测的。

问:UTF-8和没有BOM的UTF-8有什么不同?哪个更好?

以下是一些摘自维基百科关于字节顺序标记(BOM)的文章,我相信这些文章为这个问题提供了一个可靠的答案。

关于BOM和UTF-8的含义:

Unicode标准允许使用UTF-8格式的BOM,但不要求 或推荐使用。字节顺序在UTF-8中没有意义,因此 在UTF-8中唯一使用的是在文本流开始时发出信号 以UTF-8编码。

不使用BOM的参数:

不使用BOM的主要动机是向后兼容性 使用不支持unicode的软件…另一个不这样做的原因 使用BOM是为了鼓励UTF-8作为“默认”编码。

使用BOM的参数:

The argument for using a BOM is that without it, heuristic analysis is required to determine what character encoding a file is using. Historically such analysis, to distinguish various 8-bit encodings, is complicated, error-prone, and sometimes slow. A number of libraries are available to ease the task, such as Mozilla Universal Charset Detector and International Components for Unicode. Programmers mistakenly assume that detection of UTF-8 is equally difficult (it is not because of the vast majority of byte sequences are invalid UTF-8, while the encodings these libraries are trying to distinguish allow all possible byte sequences). Therefore not all Unicode-aware programs perform such an analysis and instead rely on the BOM. In particular, Microsoft compilers and interpreters, and many pieces of software on Microsoft Windows such as Notepad will not correctly read UTF-8 text unless it has only ASCII characters or it starts with the BOM, and will add a BOM to the start when saving text as UTF-8. Google Docs will add a BOM when a Microsoft Word document is downloaded as a plain text file.

有或没有BOM,哪个更好:

IETF建议,如果一个协议(a)总是使用UTF-8, 或者(b)有其他方式表明使用的是什么编码, 那么它“应该禁止使用U+FEFF作为签名。”

我的结论是:

仅在与软件应用程序的兼容性是绝对必要的情况下使用BOM。

还要注意,虽然引用的维基百科文章指出,许多Microsoft应用程序依赖BOM来正确检测UTF-8,但并非所有Microsoft应用程序都是如此。例如,正如@barlop所指出的,当使用带有UTF-8†的Windows命令提示符时,此类类型和更多的命令不期望出现BOM。如果存在BOM,它可能会像其他应用程序一样出现问题。


†chcp命令通过代码页65001提供对UTF-8(没有BOM)的支持。