为什么我要使用Unicode签名字节顺序标记(BOM)?

时间:2009-06-25 19:06:32

标签: unicode encoding utf-8 byte-order-mark

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

8 个答案:

答案 0 :(得分:17)

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

当读取未知的UTF-16文件时,如何判断使用哪两个? 唯一的解决方案是在文件中放置某种易于识别的标记,无论使用何种字节顺序,都不会将其误认为是其他任何内容。

这就是BOM的作用。

你需要吗?只有当你1)使用UTF编码时才会出现字节顺序问题(对UTF-16很重要,但UTF8总是看起来一样,无论字节顺序如何),文件将被共享与外部应用程序。

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

答案 1 :(得分:9)

来自Unicode Consortium的UTF and BOM FAQ的一些摘录可能会有所帮助。

  

问:什么是BOM?

     

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

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

  

问:BOM在哪里有用?

     

A: BOM在文本输入的文件开头非常有用,但是不知道它们是大端还是小端格式 - 它也可以用作提示指示文件是Unicode,而不是传统编码,此外,它还充当所使用的特定编码格式的签名。

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

  

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

     

A:不,无论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表示big-endian UTF-16文本,使用UTF-16LE表示little-endian UTF-16文本。如果您使用BOM,请将文本标记为UTF-16。

它提到了标记数据格式的概念。这意味着从数据本身指定格式带外。如果您可以使用这样的工具,那就太好了,但通常情况下并非如此,特别是当旧系统正在为Unicode进行改造时。

答案 2 :(得分:3)

BOM表示文件所在的Unicode编码。没有这种区别,unicode阅读器就不会知道如何读取文件。

但是,UTF-8不需要BOM。

查看Wikipedia article

答案 3 :(得分:2)

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

答案 4 :(得分:2)

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

您使用的唯一原因是在具有不同字节顺序的平台之间发送UTF-16或UTF-32数据,但(1)大多数人无论如何都使用UTF-8,以及(2)MIME {{1参数提供了更好的机制。

答案 5 :(得分:0)

UTF16和UTF32可以用Big-Endian和Little-Endian形式编写。您可以尝试通过分析在任何一个endianess中处理文件的结果来启发式地确定endianess,但为了节省您的所有麻烦,BOM可以立即告诉您。

UTF-8并不真正需要BOM,因为你逐字节解码它。

答案 6 :(得分:0)

无论您是在创建文本文件时自己使用它们,在阅读文本文件时都可能需要注意。即,在文件的开头检测并跳过(并且理想地相应地处理)BOM。我遇到了一些有它的问题,最初引起了我的一些问题,直到我弄清楚发生了什么。

答案 7 :(得分:0)

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