什么是XML BOM以及如何检测它?

ANSI XML文档中的BOM究竟是什么?是否应将其删除? XML文档应该是UTF-8吗? 谁能告诉我一个可以检测BOM的Java方法? BOM由字符EF BB BF组成。

对于ANSI XML文件,它实际上应该被删除。 如果你想使用UTF-8,你真的不需要它。 仅适用于UTF-16和UTF-32。

字节顺序标记(或BOM)是在以UTF-8,UTF-16或UTF-32编码的Unicode文件的最开头添加的特殊标记。 它用于指示文件是使用big-endian还是little-endian字节顺序。 对于UTF-16和UTF-32,BOM是强制性的,但对于UTF-8,它是可选的。

关于如何在java中检测这个问题。

检查以下问题的答案:Java: 如何确定流的正确charset编码,如果您现在想要自己确定BOM(风险由您自己承担),请检查此代码Java提示:如何读取文件和自动指定正确的编码 。

基本上只需读取前几个字节,然后确定您是否找到了BOM。

字节顺序标记可能是这些字节序列之一:

UTF-8 BOM: ef bb bf UTF-16BE BOM: fe ff UTF-16LE BOM: ff fe UTF-32BE BOM: 00 00 fe ff UTF-32LE BOM: ff fe 00 00 

这些是Unicode代码点U + FEFF的各种编码forms。 这可以表示为使用'\uFEFF'的Java char文字(Java char值隐式为 UTF-16)。 由于U + FEFF不在大多数编码中,因此BOM代码点不可能对它们进行编码。 ( 有关使用Java在此处编码BOM的更多信息 。)

对于BOM和XML,它们是可选的(另请参见Unicode BOM常见问题解答 )。 如果在声明中指定了编码,则在XML中检测编码是相对简单的。 始终确保XML声明( )与用于编写文档的编码相匹配。 如果您对此严格要求,解析器应该能够正确解释您的文档。 ( 关于编码检测的XML规范。 )

我主张尽可能编码为Unicode(另请参阅Unicode的10条命令 )。 也就是说,XML允许通过转义实体表示任何Unicode字符(例如’A’可以用A表示),因此不一定要避免数据丢失。

不要在utf-8文件中插入BOM:如果合并了两个这样的文件,最后会在中间放置一个可能会破坏应用程序的BOM,或者导致xml解析器抛出exception。

OP:

谁能告诉我一个可以检测BOM的Java方法?

org.apache.commons.io.input.BOMInputStream Javadocs:

此类检测这些字节,如果需要,可以自动跳过它们并将后续字节作为流中的第一个字节返回。