【发布时间】:2010-11-05 22:48:09
【问题描述】:
这些已经过时了吗?它们似乎是有史以来最糟糕的想法——在文件内容中嵌入任何人都看不到的东西,但会影响文件的功能。我不明白我为什么想要一个。
【问题讨论】:
标签: unicode encoding utf-8 byte-order-mark
这些已经过时了吗?它们似乎是有史以来最糟糕的想法——在文件内容中嵌入任何人都看不到的东西,但会影响文件的功能。我不明白我为什么想要一个。
【问题讨论】:
标签: unicode encoding utf-8 byte-order-mark
在某些情况下它们是必要的,是的,因为 UTF-16 既有 little-endian 也有 big-endian 实现。
当读取一个未知的 UTF-16 文件时,你怎么知道使用的是哪一个? 唯一的解决方案是在文件中放置某种易于识别的标记,无论使用哪种字节序,都不会被误认为是其他任何东西。
这就是 BOM 的作用。
你需要一个吗?仅当您是 1) 在字节序存在问题的情况下使用 UTF 编码(这对 UTF-16 很重要,但无论字节序如何,UTF8 总是看起来相同),并且文件将被共享与外部应用程序。
如果您自己的应用程序是唯一要读取和写入文件的应用程序,您可以省略 BOM,只需一劳永逸地决定您要使用哪种字节序。但如果另一个应用程序必须读取文件,它不会提前知道字节序,因此添加 BOM 可能是个好主意。
【讨论】:
cat file1 file2 file3 > file123。
Unicode 联盟UTF and BOM FAQ 的一些摘录可能会有所帮助。
问:什么是 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 的数据?
答:使用标签 UTF-16BE 表示大端 UTF-16 文本,使用 UTF-16LE 表示小端 UTF-16 文本。如果您确实使用 BOM,请将文本标记为简单的 UTF-16。
它提到了标记数据格式的概念。这意味着从数据本身指定格式带外。如果您可以使用这样的工具,那就太好了,但通常不是这样,尤其是在为 Unicode 改造旧系统时。
【讨论】:
当您使用 UTF-8 标记此内容时,我会说您不需要 BOM。 Byto Order Marks 仅对 UTF-16 和 UTF-32 有用,因为它会通知计算机文件是否在 Big Endian or Little Endian 中。一些文本编辑器可能会使用字节顺序标记来决定文档使用什么编码,但这不是 Unicode 标准的一部分。
【讨论】:
【讨论】:
cat 需要关心编码是什么?
“BOM”是 Unicode 早期的遗留物,当时人们认为使用 Unicode 意味着使用 16 位字符。在像 UTF-8 这样只有一个字节顺序的编码中完全没有意义。 U+FEFF 的选择对于 UTF-32 也是次优的,因为它无法区分所有可能的中端字节顺序(这样做需要用 4 个不同字节编码的 BOM)。
您使用 UTF-16 或 UTF-32 数据的唯一原因是在具有不同字节顺序的平台之间发送 UTF-16 或 UTF-32 数据,但是 (1) 大多数人仍然使用 UTF-8,以及 (2) MIME charset参数提供了更好的机制。
【讨论】:
UTF16 和 UTF32 可以写成 Big-Endian 和 Little-Endian 形式。您可以尝试通过分析以任一字节序处理文件的结果来启发式地确定字节序,但为了省去您的麻烦,BOM 可以立即告诉您。
UTF-8 并不真正需要 BOM,因为您逐字节解码它。
【讨论】:
无论您是否在创建文本文件时自己使用这些,在您阅读文本文件时可能都值得注意。即在文件开头检测并跳过(并理想地处理)BOM。我遇到了一些它,最初导致了我的一些问题,直到我弄清楚发生了什么。
【讨论】:
由于 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 序列,但在我看来,检查文件的前三个字节更容易。
【讨论】: