探测文本文件编码的问题
通常的办法,是读取文件的前几个字节,很多文本文件是在头部用几个字节(BOM,Byte Order Mark)来标识文本文件的编码类型,比如:
UNICODE(little endian): FFFE
Unicode(big endian): FEFF
UTF-8:EFBBBF
等等。
直接先测试。写一段程序(源程序在下面),从本地找一个UTF-8编码的文件里读前几个字节,查看16进制的结果,-_-! 读出来的直接是第一个字符,没有所谓的BOM(EFBBBF,把FEFF按UCS到UTF-8的转换可得到)头,换另外一些文件,都找不到文件所谓的BOM头,但用UE打开看16进制编码确实能看到(UTF-8编码的文件显示FFFE),不解!
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(absolute_file_path));
int p = (bis.read() << 8) + bis.read();
bis.close();
System.out.println(Integer.toHexString(p));
各种测试,大半天,发现用notepad++打开文件,菜单中 格式-->以UTF-8格式编码,保存。运行程序,BOM头读出来了,如果在格式中选择以UTF-8 无BOM格式编码,就读不出来BOM头。
但是用UE十六进制编码查看,却又能看到文件头的FFFE两个字节(UE内部的自动转换,所以看到的不是EFBBBF,不要被这个误导)。
这是什么问题?看样子只能解释为UE会根据文件的内容<不光是BOM头>,来判断文件内容是否是UTF-8编码。查看UE的设置里有一项-->自动检测 UTF-8文件,设置为OFF,再用UE十六进制查看,能看到UTF-8的BOM头了,但是如果有非ascii的字符,显示就有问题了!看样子,UE不会仅根据BOM头去判断文件是否是UTF-8类型???
问题:用nodepad++打开一个UTF-8的文本文件,选择以UTF-8 无BOM格式编码,程序就读不出来BOM头了,但是用UE打开十六进制编辑,又能看到了BOM头,为什么?
解释:UE是根据文件内容判断文件编码格式?在以十六进制方式显示文件内容时,会在头部加上BOM头?用notepad打开该文件,选择另存为,也能看到文件是以UTF-8格式编码,难道Notepad++是监测文件内容来判断文件格式?而不是传说中的根据BOM头?
或者另外一种解释:测试的JAVA代码,从stream读字节,会忽略BOM头?但是用notepad++选择以UTF-8格式编码时,会确实能读出来BOM头,所以代码会忽略BOM头这个结论应该不成立
看样子是第一种解释要合理一点了。如果有朋友有更合理的解释,欢迎提出!
参考:http://baike.baidu.com/view/414935.htm
http://zh.wikipedia.org/wiki/UTF-8