在Mac下读取Windows下生成的txt文件时总是出现乱码,试了好多种办法都不奏效,几欲崩溃。在编码问题上已经栽了好多次跟头了,之前搞PHP+MySql时也被编码问题整得焦头烂额。
好在最终还是找到了解决办法,思路如下。
Windows平台编码
Windows平台的默认编码是ANSI,所谓ANSIAmerican National Standards Institute,ANSI)就是就是用2个字节来表示一个字符的方法,ANSI编码使用0X80-0xFF(ASCII使用00000000-11111110)七位来表示128个字符。
不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。
MAC平台编码
MAC平台使用的是Unique编码方案,而JVM的默认编码依赖于平台,所以一开始使用BufferedReader reader = new BufferedReader(new FileReader("file.txt"))
时,使用的是Mac平台默认的解码器。这点可以在JDK文档中找到:
Every instance of the Java virtual machine has a default charset, which may or may not be one of the standard charsets. The default charset is determined during virtual-machine startup and typically depends upon the locale and charset being used by the underlying operating system.
同时,通过追踪BufferedReader,终于在StreamDecoder类中发现if(var2 == null) {
var3 = Charset.defaultCharset().name();
}
而System.out.print(Charset.defaultCharset().name());
妥妥地输出UTF-8
解决方案
BufferedReader reader = new BufferedReader(new InputStreamReader
(new FileInputStream(“file.txt”), "gbk"));
其中的gbk一般可以换成gb2312或者gb18030,三者只有很小的差别,版本顺序为gb2312->gbk->gb18030。另外,new FileReader("file.txt")
是对new InputStreamReader(new FileInputStream(“file.txt”))
的简单封装。
参考资料
- Mac 的应用环境(二)语言、输入法和字体:http://www.jianshu.com/p/507e88f3b519
- ANSI编码:http://baike.baidu.com/link?url=7lfY09Rt6chkepLWRZzGcg61YJJd93tR5C3tqt8WzOyhaTZe3Z-4m7QjyMY9x9smjCSzOCtqbJl-sgoP2p-8bU9AMjSVE9ZL7VHLxq8AMcu
- Class Charset:http://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html
- 中文编码杂谈:http://www.searchtb.com/2012/04/chinese_encode.html