说起BOM,这个问题还比较麻烦,因为BOM不可见,但用程序做不同编码文本处理时候却常常需要考虑到BOM的问题。在此之前,先对BOM做个简单认识。
先看看带BOM的文件:(下载这个文件)
源文件:
<?xml version="1.0" encoding="utf-8"?>
<ResponseData>
<Head>
<Version>0100</Version>
<RespID>634119501312903750</RespID>
<ReqID>0</ReqID>
</Head>
<Body>
<RetCode>999</RetCode>
<RetDesc>未知错误</RetDesc>
</Body>
</ResponseData>
16进制打开:
下面举个例子,针对UTF-8的文件BOM做个处理:
String xmla = StringFileToolkit.file2String(new File("D:\\projects\\mailpost\\src\\a.xml"),"UTF-8");
byte[] b = xmla.getBytes("UTF-8");
String xml = new String(b,3,b.length-3,"UTF-8");
Document doc1 = DocumentHelper.parseText(xml);
Element e1 = (Element)doc1.selectSingleNode("/ResponseData/Body/RetDesc");
Element e2 = (Element)doc1.selectSingleNode("/ResponseData/Head/RespID");
Element e3 = (Element)doc1.selectSingleNode("/ResponseData/Body/RetCode");
Element e4 = (Element)doc1.selectSingleNode("/ResponseData/Body/RetDesc");
思路是:
先按照UTF-8编码读取文件后,跳过前三个字符,重新构建一个新的字符串,然后用Dom4j解析处理,这样就不会报错了。
其他编码的方式处理思路类似,其实可以写一个通用的自动识别的BOM的工具,去掉BOM信息,返回字符串。
不过这个处理过程已经有牛人解决过了:http://koti.mbnet.fi/akini/java/unicodereader/
什么是BOM
BOM(byte-order
mark),即字节顺序标记,它是插入到以UTF-8、UTF16或UTF-32编码Unicode文件开头的特殊标记,用来识别Unicode文件的编
码类型。对于UTF-8来说,BOM并不是必须的,因为BOM用来标记多字节编码文件的编码类型和字节顺序(big-endian或little-
endian)。
在绝大多数编辑器中都看不到BOM字符,因为它们能理解Unicode,去掉了读取器看不到的题头信息。若要查看某个Unicode文件是否以BOM开头,可以使用十六进制编辑器。下表列出了不同编码所对应的BOM。
BOM
|
Encoding
|
EF BB BF
|
UTF-8
|
FE FF
|
UTF-16 (big-endian)
|
FF FE
|
UTF-16 (little-endian)
|
00 00 FE FF
|
UTF-32 (big-endian)
|
FF FE 00 00
|
UTF-32 (little-endian)
|
BOM的来历
为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO
WIDTH NOBREAK SPACE(U+FEFF)字符开头。这作为一个“特征符”或“字节顺序标记(byte-order
mark,BOM)”来识别文件中使用的编码和字节顺序。
不同的系统对BOM的支持
因为一些系统或程序不支持BOM,因此带有BOM的Unicode文件有时会带来一些问题。
1. JDK1.5以及之前的Reader都不能处理带有BOM的UTF-8编码的文件,解析这种格式的xml文件时,会抛出异常:Content is not allowed in prolog.
2. Linux/UNIX 并没有使用 BOM,因为它会破坏现有的 ASCII 文件的语法约定。
不同的编辑工具对BOM的处理也各不相同。使用Windows自带的记事本将文件保存为UTF-8编码的时候,记事本会自动在文件开头插入BOM(虽然BOM对UTF-8来说并不是必须的),但是editplus就不会这样做。
BOM与XML
XML解析读取XML文档时,W3C定义了3条规则:
1. 如果文档中有BOM,就定义了文件编码;
2. 如果文档中没有BOM,就查看XML声明中的编码属性;
3. 如果上述两者都没有,就假定XML文档采用UTF-8编码。
参考资料:
1. UTF-8, UTF-16, UTF-32 & BOM:http://www.unicode.org/faq/utf_bom.html#BOM
2. XML FAQ:Encoding:http://www.opentag.com/xfaq_enc.htm
3. Linux Unicode 编程:http://www.ibm.com/developerworks/cn/linux/i18n/unicode/linuni/
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
http://koti.mbnet.fi/akini/java/java_utf8_xml/
http://koti.mbnet.fi/akini/java/unicodereader/
http://www.unicode.org/faq/utf_bom.html
分享到:
相关推荐
"标签"中的"BOM UTF-8 idea"进一步明确了这个工具的功能焦点,BOM指的是文件头的字节顺序标记,UTF-8是与之相关的编码格式,而idea则强调了该工具与IntelliJ IDEA集成开发环境的关联。 至于压缩包内的"去除BOM文件...
BOM,即字节顺序标记,是UTF-8编码中可选的一部分,用于标识数据流的字节顺序。在大多数情况下,BOM在UTF-8编码中并不必要,因为它默认是小端序,但对于某些程序或系统,BOM可能有助于识别文件的编码方式。 在处理...
标题“BOM相关资料”暗示了我们即将探讨的是关于“Byte Order Mark”,即字节顺序标记的专题。BOM是Unicode编码格式中的一个特殊字符,用于标识文本文件或流的字节顺序。在处理跨平台或多语言的文本数据时,BOM的...
- 在UTF-16BE中,“字节顺序标记”(Byte Order Mark, BOM)为`FEFF`。 - **示例**:在Java中,如果使用UTF-16BE编码一个字符串,那么该字符串将按照大端字节序进行编码。 #### 1.2 UTF-16LE (Little Endian) - *...
例如,GBK编码的文件头通常会有特定的字节序列,而UTF-8文件可能会包含BOM(字节顺序标记)。 2. **字节流与字符流**:在Java中,I/O操作分为字节流和字符流。处理不同编码的文件时,通常我们会先使用字节流读取...
在Unicode和UTF-16编码下,无论是英文字符还是汉字,都需要额外的两个字节来表示字节顺序,这是因为UTF-16使用字节顺序标记(BOM,Byte Order Mark)。BOM是一个特殊字符,用于标识字节流的字节顺序。例如,UTF-16BE...
标题中的“文件BOM批量删除工具”指的是一个专门设计用于处理文本文件的软件,它的主要功能是删除UTF-8、UTF-16和UTF-32编码格式的文件中的字节顺序标记(BOM)。BOM,即Byte Order Mark,是在某些Unicode编码中用于...
- 检测文本文件的编码可以通过观察文件的字节顺序标记(BOM)或手动检查。对于程序来说,可以读取文件的前几个字节,然后根据这些字节判断文件的编码类型。例如,可以编写一个工具函数来检测文件的编码: ```java ...
在处理字节流编码时,我们通常会遇到诸如字符集、字节顺序标记(BOM)、解码与编码的过程等概念。下面我们将深入探讨这些知识点。 首先,让我们了解什么是字节流。字节流是计算机处理数据的一种方式,无论是文件...
这种编码方式在处理Unicode文本时非常高效,但可能需要额外的字节顺序标记(BOM)来确定字节顺序。 5. **UTF-16LE (Little Endian)**:与UTF-16BE相反,LE表示“小端”字节顺序,即最低有效字节在前。同样,也需要BOM...
2. 字节顺序标记(BOM):UCS2通常有字节顺序标记,而在GB2312中则没有,处理时需要考虑BOM的存在与否。 3. 错误检测与处理:转换过程中可能出现无法匹配的编码值,需要有适当的错误处理机制,如忽略、替换或抛出...
打开文件 -> 编辑 -> 转换为UTF-8无BOM(无字节顺序标记)。 - **Sublime Text**:同样功能强大的编辑器,安装“ConvertToUTF8”插件后,文件 -> 转换为UTF-8。 3. **命令行工具转换**: - **Linux/Mac**:使用`...
注意,此步骤可能不完全准确,因为某些文件可能本身就是ASCII编码,没有明确的BOM(字节顺序标记)。 3. **转换编码**:对于检测到GBK编码的文件,使用`java.nio.file.Files`类的`readAllBytes`和`write`方法,配合...
3. **处理BOM头**:某些Unicode编码(如UTF-8、UTF-16)可能包含字节顺序标记(BOM),在读取前需要检测并去除BOM,以防止解析错误。 4. **使用第三方库**:如果Java标准库无法满足需求,可以考虑使用开源库,如...
8. **ByteOrderMark**: 用于识别和处理字节顺序标记(BOM),常在处理UTF-8或UTF-16编码的文件时用到。 与"commons-fileupload.jar"配合使用时,Apache Commons IO 可以帮助处理文件上传过程中的临时文件操作、流的...
工具通常采用“字节顺序标记”(BOM)识别、统计字符频率、比较编码表等多种方法来自动检测文件的编码。BOM是某些编码(如UTF-16和UTF-8)在文件开头放置的一个特殊标记,用于表明其编码类型。而统计字符频率和比较...
UTF-8没有字节顺序问题,而UTF-16则需要考虑字节序,通过BOM(字节顺序标记)来指示字节流的顺序。 最后,UTF格式有多种变体,如UTF-8和UTF-16。UTF-8以其高效存储常见字符的特性被广泛应用,而UTF-16则更适合内部...
8. **ByteOrderMark**: 用于识别和处理字节顺序标记(BOM),常见于UTF-16和UTF-8编码的文件中。 9. **InputStreamReaderWrapper** 和 **OutputStreamWriterWrapper**: 这些类提供了包装功能,可以在输入/输出流之...
1. **检查BOM(Byte Order Mark)**:UTF-8允许在文件开头放置一个可选的字节顺序标记(BOM),其字节序为EF BB BF。如果文件以这三个字节开头,那么可以初步判断为UTF-8编码。但没有BOM的UTF-8文件也是存在的,所以...
字节顺序标记(BOM)处理。 大文件支持:部分方法设计用于处理大型文件,避免一次性加载到内存中。 应用场景: 任何需要进行文件或数据流操作的Java应用,包括但不限于文件上传下载、日志处理、数据导入导出、备份...