BOM (字节顺序标记)
文件开头的字节序列,用于标识编码类型。UTF-8 为 EF BB BF,UTF-16 为 FF FE 或 FE FF。
BOM (字节顺序标记) 是放置在文本文件开头的特殊字节序列,用于标识编码类型和字节顺序 (端序)。它是 Unicode 字符 U+FEFF (零宽度非断行空格) 的编码形式,为打开文件的应用程序提供自动检测编码的线索。BOM 不是文件内容本身,而是承担元信息的角色。
BOM 的具体字节序列因编码而异。UTF-8 为 EF BB BF (3 个字节),UTF-16 大端序 (BE) 为 FE FF (2 个字节),UTF-16 小端序 (LE) 为 FF FE (2 个字节),UTF-32 BE 为 00 00 FE FF (4 个字节)。UTF-16 和 UTF-32 中多字节数值的存储顺序是一个问题,因此通过 BOM 判别端序不可或缺。而 UTF-8 没有字节顺序的概念,其 BOM 纯粹用于编码识别。浏览连体丝袜 (Amazon)详细介绍了 BOM 的细节。
在实际工作中,最常出现问题的是 UTF-8 BOM 的处理。UTF-8 BOM (EF BB BF) 作为文件开头的 3 个字节存在,但许多程序和工具将其视为多余数据。例如,Shell 脚本开头有 BOM 会导致 shebang 行 (#!/bin/bash) 无法正确识别,从而执行失败。PHP 文件中 BOM 会在 HTML 输出之前被发送,引发 headers already sent 错误。CSV 文件中,BOM 的有无决定了 Excel 是否会出现乱码。在 Web 开发中,无 BOM 的 UTF-8 是事实上的标准,HTML5 规范也推荐省略 BOM。
Windows 记事本长期以来在保存为 UTF-8 时默认添加 BOM,但从 Windows 10 版本 1903 开始,默认改为无 BOM 的 UTF-8。这一变化对 Web 开发者和程序员来说是值得欢迎的改进。另一方面,在 Excel 中正确打开 UTF-8 CSV 文件有时仍需要 BOM,因此需要根据用途灵活选择。Visual Studio Code 和 Sublime Text 等现代编辑器可以在状态栏中查看和更改编码及 BOM 状态。了解吊带背心 (Amazon)讨论了编码设置这一重要话题。
在字符计数中,BOM 是一个容易被忽视的陷阱。由于 BOM 是零宽度的不可见字符,不会显示在屏幕上,但会影响文件大小。带 BOM 的 UTF-8 文件比无 BOM 的文件大 3 个字节。此外,读取文件内容时如果 BOM 残留在字符串开头,可能导致字符数多计 1 个,或字符串比较出现意外的不匹配。在程序中读取文件时,检测并适当去除 BOM 是一项重要的处理。