BOM(byte-order mark)

来源:互联网 发布:直播间网站源码 编辑:程序博客网 时间:2024/06/06 02:27

BOM(byte-order mark)

2011-11-02 创建

    最近接连遇到两个奇怪的事情,一,在WINDOWS CYGWIN下可以编译的C++代码文件,到了LINUX环境下使用GCC报存在游离的字符,导致编译失败。

    (gcc编译报错:程序中有游离的‘\357’‘\273’‘\277’等 ,其原因有可能是

           1,误用了全角的符号和空格等,

           2,BOM字符。)

    二,在WINDOWS下正常解析的XML文件在LINUX设备上报“前导字符错误”。

   最后发现这些问题都是微软的BOM字符惹的祸。

 

什么是BOM 
    BOM(byte-order mark),即字节顺序标记,它是插入到以UTF-8、UTF16或UTF-32编码Unicode文件开头的特殊标记,用来识别Unicode文件的编码类型。具体编码如下表:
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)

   微软建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE(U+FEFF)字符开头。这作为一个“特征符”来识别文件中使用的编码和字节顺序。BOM的本意不错,但它并不是一个通用标准,从而导致了很多不兼容的问题。

1. JDK1.5以及之前的Reader都不能处理带有BOM的UTF-8编码的文件,解析这种格式的xml文件时,会抛出异常:Content is not allowed in prolog.

2. Linux/UNIX 并没有使用 BOM,因为它会破坏现有的 ASCII 文件的语法约定。

3, 目前GCC编译器不接受带有BOM的源代码文件

   不同的编辑工具对BOM的处理也各不相同。使用Windows自带的记事本将文件保存为UTF-8编码的时候,记事本会自动在文件开头插入BOM(虽然BOM对UTF-8来说并不是必须的),但是其它编辑器的就不会这样做,或者有专门的选项决定其行为。

   当然解决BOM兼容性这个问题也简单,使用工具将带有BOM的文件保存成不带BOM的文件,(例如可以使用Visual Studio进行转换,选择“文件/高级保存选项”,选择保存为 Unicode(UTF-8 无签名) - 代码页65001 即可),或者自己使用工具删除前导字符就可以了。如果是在程序中处理,可以以二进制方式打开文件,判断一下是否存在BOM字符,然后再进行删除或忽略BOM字符的操作。

   最后,如果这时你的文档为带BOM的UTF-8文件,使用的二进制编辑工具又恰好是ULTRAEDIT,很可能会碰到另外的奇怪的问题,将该文件二进制显示,会发现前导字节为FFFE,以及文档中的英文字符是两个字节,而不是UTF-8中的一个字节,自己编写一个小的二进制读取工具会发现文档并没有问题,前导字节是EFBBBF,英文字符也是一个字节的。原因是缺省配置的ULTRAEDIT对UTF-8进行了自动的转换,转为UNICODE LE格式,如果关闭其“自动检测UTF-8格式数据”的选项,可以发现二进制显示没有问题,但文本显示中的前导字节和中文等字符会变成乱码。因此该选项决定了ULTRAEDIT能够正确显示UTF-8文件的文本格式还是二进制格式,一般我们还是选择正确的文本显示,因为大部分情况下需要的是文本编辑。但如果使用ULTRAEDIT删除前导的BOM,需要暂时关闭该选项后再进行二进制编辑。

自动转换为UNICODE LE的UTF8编码XML文件二进制显示

不自动转换的带有BOM的UTF8编码XML文件二进制显示

不自动转换的不带有BOM的UTF8编码XML文件二进制显示


引用自:http://blog.csdn.net/firefight/article/details/6927328

0 0