0%

Java读取txt文件乱码的解决

在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”))的简单封装。

参考资料

  1. Mac 的应用环境(二)语言、输入法和字体:http://www.jianshu.com/p/507e88f3b519
  2. ANSI编码:http://baike.baidu.com/link?url=7lfY09Rt6chkepLWRZzGcg61YJJd93tR5C3tqt8WzOyhaTZe3Z-4m7QjyMY9x9smjCSzOCtqbJl-sgoP2p-8bU9AMjSVE9ZL7VHLxq8AMcu
  3. Class Charset:http://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html
  4. 中文编码杂谈:http://www.searchtb.com/2012/04/chinese_encode.html