9

这些已经过时了吗?它们似乎是有史以来最糟糕的想法——在文件内容中嵌入任何人都看不到的东西,但会影响文件的功能。我不明白我为什么想要一个。

4

8 回答 8

17

它们在某些情况下是必要的,是的,因为 UTF-16 既有 little-endian 也有 big-endian 实现。

当读取一个未知的 UTF-16 文件时,你怎么知道这两者中的哪一个被使用了?唯一的解决方案是在文件中放置某种易于识别的标记,无论使用哪种字节序,都不会被误认为是其他任何东西。

这就是 BOM 的作用。

你需要一个吗?仅当您是 1) 在字节序存在问题的情况下使用 UTF 编码(这对 UTF-16 很重要,但无论字节序如何,UTF8 总是看起来相同),并且该文件将与外部应用程序共享。

如果您自己的应用程序是唯一要读取和写入文件的应用程序,您可以省略 BOM,只需一劳永逸地决定您将使用哪种字节序。但是如果另一个应用程序必须读取文件,它不会提前知道字节序,所以添加 BOM 可能是个好主意。

于 2009-06-25T19:13:27.750 回答
9

Unicode 联盟的UTF 和 BOM 常见问题解答中的一些摘录可能会有所帮助。

问:什么是 BOM?

答:字节顺序标记(BOM)由数据流开头的字符代码 U+FEFF 组成,它可以用作定义字节顺序和编码形式的签名,主要用于未标记的纯文本文件。在某些更高级别的协议下,在该协议中定义的 Unicode 数据流中可能强制(或禁止)使用 BOM。(强调我的。)

我不会确切地说字节顺序标记嵌入在数据中。相反,它是数据的前缀。当字符是数据流中的第一件事时,它只是一个字节顺序标记。其他任何地方,它是零宽度不间断空间。不尊重字节顺序标记的 Unicode 感知程序无论如何都不会受到它的存在的真正伤害,因为字符是不可见的,并且在文本块开头的单词连接器只会将下一个字符连接到任何内容,所以它没有效果。

问:BOM 在哪里有用?

答: BOM 在以文本形式键入的文件的开头很有用,但不知道它们是大端格式还是小端格式 - 它也可以作为指示文件是 Unicode 格式的提示,如与传统编码相反,此外,它充当所使用的特定编码形式的签名。

因此,当您的程序能够处理 Unicode 的多种编码时,您会需要一个 BOM。您的程序在解释其输入时如何知道使用哪种编码?

问:当使用 BOM 时,它是否仅在 16 位 Unicode 文本中?

答:不,无论 Unicode 文本如何转换,BOM 都可以用作签名:UTF-16、UTF-8、UTF-7 等。构成 BOM 的确切字节将是任何 Unicode 字符 U+FEFF通过该转换格式转换成。在这种形式中,BOM 用于指示它是一个 Unicode 文件,以及它采用哪种格式。

这可能是当今最常使用 BOM 的情况。它将 UTF-8 编码的文本与任何其他编码区分开来;它并没有真正标记字节的顺序,因为 UTF-8 只有一个顺序。

如果您正在设计自己的协议或数据格式,则不需要使用 BOM。常见问题解答中的另一个问题涉及到:

问:如何标记不将 U+FEFF 解释为 BOM 的数据?

A:使用标签 UTF-16BE 表示大端 UTF-16 文本,使用 UTF-16LE 表示小端 UTF-16 文本。如果您确实使用 BOM,请将文本标记为简单的 UTF-16。

它提到了标记数据格式的概念。这意味着从数据本身指定带外格式。如果您可以使用这样的工具,那就太好了,但通常不是这样,尤其是在为 Unicode 改造旧系统时。

于 2009-06-25T19:55:16.667 回答
3

BOM 表示文件采用哪种 Unicode 编码。没有这种区别,Unicode 阅读器将不知道如何读取文件。

但是,UTF-8 不需要 BOM。

查看维基百科的文章

于 2009-06-25T19:13:07.843 回答
3

当你用 UTF-8 标记它时,我会说你不需要 BOM。Byto Order Marks 仅对 UTF-16 和 UTF-32 有用,因为它会通知计算机文件是Big Endian 还是 Little Endian。一些文本编辑器可能使用字节顺序标记来决定文档使用什么编码,但这不是 Unicode 标准的一部分。

于 2009-06-25T19:27:41.013 回答
3

“BOM”是 Unicode 早期的遗留物,当时假定使用 Unicode 意味着使用 16 位字符。在像 UTF-8 这样只有一个字节顺序的编码中,这是完全没有意义的。U+FEFF 的选择对于 UTF-32 也是次优的,因为它无法区分所有可能的中端字节顺序(这样做需要用 4 个不同字节编码的 BOM)。

您使用它的唯一原因是在具有不同字节顺序的平台之间发送 UTF-16 或 UTF-32 数据时,但是 (1) 大多数人仍然使用 UTF-8,并且 (2) MIMEcharset参数提供了更好的机制。

于 2010-08-14T22:32:37.517 回答
0

UTF16 和 UTF32 可以写成 Big-Endian 和 Little-Endian 两种形式。您可以尝试通过分析以任一字节序处理文件的结果来启发式地确定字节序,但为了省去您的所有麻烦,BOM 可以立即告诉您。

不过,UTF-8 并不真正需要 BOM,因为您逐字节对其进行解码。

于 2009-06-25T19:14:09.400 回答
0

无论您在创建文本文件时是否自己使用这些,在阅读文本文件时都可能值得注意。即在文件开头检测并跳过(并理想地处理)BOM。我遇到了一些它,最初导致了我的一些问题,直到我弄清楚发生了什么。

于 2011-11-08T18:24:33.613 回答
0

由于 UTF16 和 UTF32 BOM 告诉内容是 Big-Endian 还是 Little-Endian 格式,并且内容是 Unicode,UTF-8 BOM 将文件分类为 utf-8 编码。如果没有 UTF-8 BOM,你怎么知道它是 ANSI 文件还是 UTF-8 编码文件?UTF-8 BOM 当然不会告诉字节序,因为 utf-8 始终是字节流,但它会告诉内容是 utf-8 编码的 Unicode 还是 ANSI。当然,您可以扫描有效的 utf-8 序列,但在我看来,检查文件的前三个字节更容易。

于 2016-03-03T10:53:41.803 回答