字节顺序标记(byte order mark,BOM)由数据流开始处的字符代码 U + FEFF
组成,它可以用作定义字节顺序和编码形式的签名,主要是无标记的明文文件。在某些更高级别的协议中,在该协议中定义的 Unicode
数据流中可能强制(或禁止)使用 BOM。
BOM 在哪里有用?
答: BOM 在以文本形式输入的文件开始时很有用,但不知道它们是大端还是小端格式——它还可以作为一个提示,表明文件是 Unicode 格式的,而不是传统编码格式的,此外,它还可以作为所使用的特定编码格式的签名。
问: “端末”是什么意思?
答:
长于一个字节的数据类型可以存储在计算机存储器中,最高有效字节(MSB)可以是第一个字节,也可以是最后一个字节。前者叫做大端,后者叫做小端。当数据以与原始系统内存中相同的字节顺序交换时,它们在接收系统上可能出现错误的字节顺序。在这种情况下,BOM
类似于0xFFFE,它是非字符的,允许接收系统在处理数据之前应用字节反转。UTF-8是面向字节的,因此没有这个问题。不过,初始 BOM
可能有助于将数据流标识为 UTF-8。
问: 当使用 BOM 时,是否只使用16位 Unicode 文本?
答:
不,无论 Unicode 文本如何转换,BOM 都可以用作签名: UTF-16、 UTF-8、
UTF-7等等。构成物料清单的确切字节将是由该转换格式转换成的任何 Unicode字符 FEFF。在这种形式下,BOM 用于指示它是一个
Unicode 文件,以及它所采用的格式。例子:
BytesEncoding Form
00 00 FE FFUTF-32, big-endian
FF FE 00 00UTF-32, little-endian
FE FFUTF-16, big-endian
FF FEUTF-16, little-endian
EF BB BFUTF-8
问: UTF-8数据流能否包含 BOM 字符(UTF-8格式) ?如果是,那么我是否仍然可以假设剩余的 UTF-8字节是大端顺序?
答:
是的,UTF-8可以包含 BOM。但是,它对字节流的 endianness 没有影响。UTF-8始终具有相同的字节顺序。初始 BOM
仅用作签名ーー表示原本未标记的文本文件是 UTF-8。注意,UTF-8编码数据的一些接收者并不期望 BOM。当
UTF-8在8位环境中被透明地使用时,BOM 的使用将干扰任何在开始时需要特定 ASCII 字符的协议或文件格式,例如使用“ # !”在
Unix shell 脚本的开头。
问: 在文件中间 U + FEFF 应该怎么做?
答:
在没有协议支持其作为 BOM 使用的情况下,如果不是在文本流的开头,U + FEFF
通常不应该出现。为了向后兼容,它应该被视为零宽度不换行空格(zwnbSP) ,然后成为文件或字符串内容的一部分。与 ZWNBSP 相比,U +
2060 WORD JOINER 在表达词汇连接语义方面的优势非常明显,因为它不能与 BOM 混淆。在设计标记语言或数据协议时,可以将 U +
FEFF 的使用限制在字节顺序标记的使用范围内。在这种情况下,可以忽略文件中间出现的任何 U + FEFF,或者将其视为错误。
问: 我正在使用一个在文本开头有 BOM 的协议。如何表示初始 ZWNBSP?
A: 使用 U + 2060单词连接器代替。
问: 如何标记不将 FEFF 解释为 BOM 的数据?
答: 使用标记 UTF-16BE 表示大端 UTF-16文本,使用 UTF-16LE 表示小端 UTF-16文本。如果确实使用 BOM,请将文本标记为简单的 UTF-16。
问: 为什么我不总是使用需要 BOM 的协议?
答:
如果数据是类型化的,例如数据库中的字段,BOM 就是不必要的。特别是,如果文本数据流标记为 UTF-16BE、 UTF-16LE、
UTF-32BE 或 UTF-32LE,则 BOM 既不是必需的,也不是允许的。任何 FEFF 都将被解释为 ZWNBSP。
不要使用 BOM 对数据库或字段集中的每个字符串进行标记,因为这会浪费空间并使字符串串联复杂化。此外,它还意味着两个数据字段可能具有完全相同的内容,但不是二进制相等的(其中一个字段以 BOM 开头)。
问: 我应该如何处理 BOM?
答: 以下是一些指导方针:
一个特定的协议(例如微软的。Txt 文件)可能需要在某些 Unicode 数据流(如文件)上使用 BOM。当您需要遵守这样的协议时,使用 BOM。
有些协议允许在未标记文本的情况下使用可选的 BOM,
如果已知文本数据流为纯文本,但编码未知,BOM 可用作签名。如果没有 BOM,编码可以是任何东西。
如果已知文本数据流是纯 Unicode 文本(但不知道是哪个端点) ,则可以使用 BOM 作为签名。如果没有 BOM,文本应该被解释为 big-endian。
一些面向字节的协议希望在文件的开头使用 ASCII 字符。如果在这些协议中使用 UTF-8,则应避免使用 BOM 作为编码形式签名。
如果已知数据流的精确类型(例如
Unicode big-endian 或 Unicode little-endian) ,则不应使用 BOM。特别是,当一个数据流被声明为
UTF-16BE、 UTF-16LE、 UTF-32BE 或 UTF-32LE 时,不能使用 BOM。