原创
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
最近有个问题,下载csv文件下来,用excel打开的时候,出现乱码,原因是编码是gbk,用下文所说的用utf-8编码,也不行,不知道是为什么,可能是因为我的office设置主要语言是简体中文的原因。用
OutputStreamWriter fos = new OutputStreamWriter(
new FileOutputStream(new File("c://2.csv")), "UTF-16LE");
fos.write(0xFEFF);
fos.write("你好 ");
fos.flush();
fos.close();
这种写法正常,没有出现乱码。
BOM(Byte Order Mark),是UTF编码方案里用于标识编码的标准标记,在UTF-16里本来是 FF FE,变成 UTF-8就成了 EF BB BF。这个标记是可选的,因为 UTF8字节没有顺序,所以它可以被用来检测一个字节流是否是 UTF-8编码的。微软做这种检测,但有些软件不做这种检测,而把它当作正常字符处理。
微软在自己的 UTF-8格式的文本文件之前加上了 EF BB BF三个字节 , windows上面的 notepad等程序就是根据这三个字节来确定一个文本文件是 ASCII的还是 UTF-8的,然而这个只是微软暗自作的标记 , 其它平台上并没有对 UTF-8文本文件做个这样的标记。
也就是说一个 UTF-8文件可能有 BOM,也可能没有 BOM,那么怎么区分呢?三种方法。 1,用UltraEdit-32打开文件,切换到十六进制编辑模式,察看文件头部是否有 EF BB BF。 2,用Dreamweaver打开,察看页面属性,看“包括 Unicode签名 BOM”前面是否有个勾。 3,用Windows的记事本打开,选择 “另存为”,看文件的默认编码是 UTF-8还是 ANSI,如果是 ANSI则不带 BOM。
下面是部分 BOM的介绍
在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编码了。
Windows就是使用 BOM来标记文本文件的编码方式的。
最近处理一个xml文件,用editplus看着一点问题没有,但用程序处理就会报错,错误信息翻译后如下:
属性值中不能使用字符 '