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


当前回答

问: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)的支持。

其他回答

当您希望显示以UTF-8编码的信息时,可能不会遇到问题。例如,将HTML文档声明为UTF-8,您将在浏览器中显示文档主体中包含的所有内容。

但在Windows或Linux上,当我们有文本、CSV和XML文件时,情况就不同了。

例如,Windows或Linux中的文本文件,这是最简单的事情之一,它(通常)不是UTF-8。

保存为XML并声明为UTF-8:

<?xml version="1.0" encoding="UTF-8"?>

即使声明为UTF-8,它也不能正确显示(不能读取)。

我有一串包含法语字母的数据,需要将其保存为XML以进行联合。无需从一开始就创建UTF-8文件(更改IDE中的选项和“创建新文件”)或在文件开头添加BOM

$file="\xEF\xBB\xBF".$string;

我无法将法语字母保存在XML文件中。

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,那么它可能就是。

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

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

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

红点标记BitBucket差异视图

BOM倾向于在某个地方爆炸(没有双关语)。当它突然出现时(例如,无法被浏览器、编辑器等识别),它会以奇怪的字符出现在文档的开头(例如,HTML文件、JSON响应、RSS等),并导致类似于最近奥巴马在Twitter上谈话时经历的编码问题那样的尴尬。

当它出现在难以调试的地方或当测试被忽略时,这是非常令人讨厌的。所以除非必须使用,否则最好避免使用。

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

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

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