代码之家  ›  专栏  ›  技术社区  ›  Pup

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

  •  7
  • Pup  · 技术社区  · 16 年前

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

    8 回复  |  直到 9 年前
        1
  •  17
  •   Stack Overflow is garbage    16 年前

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

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

    这就是BOM所做的。

    你需要吗?只有在1)使用UTF编码时,endianness才是一个问题(它对UTF-16很重要,但不管endianness如何,utf8看起来总是一样的)。 该文件将与外部应用程序共享。

    如果你自己的应用程序是唯一一个可以读写文件的应用程序,你可以省略BOM,只需决定一次和所有你要使用的结束语。但是,如果另一个应用程序必须读取该文件,它将不会提前知道endianness,因此添加BOM可能是一个好主意。

        2
  •  9
  •   Rob Kennedy    16 年前

    一些节选自 UTF and BOM FAQ 来自Unicode联合体可能会有所帮助。

    问:什么是物料清单?

    答: 字节顺序标记(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的数据?

    答: 使用标记utf-16be表示大尾数utf-16文本,使用utf-16le表示小尾数utf-16文本。如果确实使用了BOM,那么只需将文本标记为UTF-16。

    它提到了 标注 您的数据格式。这意味着指定格式 带外 从数据本身。如果这样的设备对你来说是很好的,但它通常不是,特别是当旧系统被改造成Unicode时。

        3
  •  3
  •   Joseph    16 年前

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

    但是,UTF-8不需要BOM。

    退房 Wikipedia article .

        4
  •  2
  •   Andrew Marsh    16 年前

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

        5
  •  2
  •   dan04    15 年前

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

    唯一的原因是在不同字节顺序的平台之间发送utf-16或utf-32数据时,(1)大多数人都使用utf-8,以及(2)mime charset 参数提供了更好的机制。

        6
  •  0
  •   Paul Dixon    16 年前

    utf16和utf32可以用big-endian和little-endian格式编写。您可以尝试通过分析在任意一个endianes中处理文件的结果来试探性地确定endianes,但是为了省去所有的麻烦,BOM可以立即告诉您。

    不过,当您逐字节解码时,UTF-8并不真正需要一个BOM。

        7
  •  0
  •   Nerdtron    13 年前

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

        8
  •  0
  •   brighty    9 年前

    由于utf16和utf32的bom说明内容是采用big-endian还是little-endian格式,而且内容也是Unicode格式,因此utf-8bom将文件分类为utf-8编码的。如果没有UTF-8BOM,如何知道它是一个ANSI文件还是一个UTF-8编码文件?当然,utf-8bom不告诉endianes,因为utf-8总是一个字节流,但它告诉内容是utf-8编码的unicode还是ansi。当然,您可以扫描有效的UTF-8序列,但在我看来,检查文件的前三个字节更容易。