UTF-8 编码的文件在处理时要注意 BOM 文件头问题

最近在给项目团队开发一个基于 Java 的通用的 XML 分析器时,设计了一个方法,能够读取现成的 XML 文件进行分析处理,当然 XML 都是采用 UTF-8 进行编码的。但是在用 UltraEdit 写了一个测试用的 UTF-8 XML 文件后,程序在读取该文件时发生错误:

Parse Fatal Error at line 1 column 1: 前言中不允许有内容。org.xml.sax.SAXParseException: Content is not allowed in prolog....

反复检查代码不可能出问题,XML 文件也是正确的,试来试去百思不得其解。于是用 IDEA 编辑器写了一个同样的 XML 文件,程序运行正常。在网上找来找去,无意中发现 UTF-8 编码居然有一个所谓的 BOM 文件头问题。那么,BOM 又是什么玩意呢?

BOM 即 Byte Order Mark,就是字节序标记。在 UCS 编码中有一个叫做“ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是 FEFF。而 FFFE 在 UCS 中是不存在的字符,所以不应该出现在实际传输中。UCS 规范建议我们在传输字节流前,先传输字符“ZERO WIDTH NO-BREAK SPACE”,这样如果接收者收到 FEFF,就表明这个字节流是 Big-Endian 的;如果收到 FFFE,就表明这个字节流是 Little-Endian 的。因此字符“ZERO WIDTH NO-BREAK SPACE”又被称作 BOM。

UTF-8 本身不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。字符“ZERO WIDTH NO-BREAK SPACE”的 UTF-8 编码是 EF BB BF。所以如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8 编码了。所以,有些编辑器会在创建并保存 UTF-8 编码的 XML 文件时自动在文件头部增加 EF BB BF 这三个字节,用来做 BOM。UltraEdit 默认就是这样,自作聪明反倒惹麻烦!IDEA 编辑器创建生成的 UTF-8 编码的 XML 文件就没有这个 BOM 文件头,所以才出现了本文开头所描述的问题现象。

后来研究了一下 UltraEdit,发现它倒是提供了一个保存选项,在第一次保存或者以后“另存为”时,选择保存为 UTF-8 without BOM 就可以了。

既然找到原因了,我想不能让各种编辑器来迁就我的程序,还是让我的程序去迁就它们吧,也就是在程序中增加自动识别 BOM 文件头的功能。这样一来,无论是否带有 BOM 文件头的 UTF-8 编码的 XML 文件,我的程序都能够兼容使用,事实上后来实现这个功能才发现,很简单,没有增加太多工作量,何乐而不为呢?

原文地址:https://www.cnblogs.com/cyberniuniu/p/5021916.html