乱码产生的原因一般有两种:
一种是解析错误;
另一种是在错误解析的基础上加上了编码转换。
(1)解析错误
比如一个GB2312编码的文件,使用UTF-8来打开,就会出现乱码。
这种情况下,只需要使用正确的编码方式即可解读。很多编辑器都有这个功能,如下图中的NotePad++:
(2)错误的解析和编码转换
使用编辑器如何改变编码方式都不对时,很有可能是文本在错误解析的基础上,还进行了编码转换。如下例子:
发送方以GBK编码发送,而接收方以UTF-8解码时,就会出现乱码现象。这时接收方想要查看正确的文本,就必须进行反向解析。将乱码以UTF-8编码得到的流再进行GBK解析,才能得到正确的文本。
在现实中,我们可能并不知道发送方和接收方的编码。所以应该以程序的方式进行如上的反向解析,如下:
public static void main(String[] args) throws Exception {
// byte[] gbkByte = "冥冥".getBytes(Charset.forName("GBK"));
// String utf8Str = new String(gbkByte, "UTF-8");
// System.out.println("得到乱码: " + utf8Str);
String garbageCharacters = "ڤڤ";
String[] charsets = new String[]{"GBK", "UTF-8", "Windows-1252"}; //可扩充
//假设原来为encode编码,用decode解析成了乱码,下面进行反向操作
for (String encode : charsets) {
for (String decode : charsets) {
if (!encode.equals(decode)) {
String newStr = new String(garbageCharacters.getBytes(decode), encode);
System.out.println("反向解析结果为:" + newStr + ",原来的编码为:" + encode + ",误解析为了:" + decode);
}
}
}
}
运行结果如下:
即可得到正确的文本。
注意:并不是所有乱码都是可恢复的,一些不能识别的字符,或经过多次编码和解析错误造成的乱码,都是难以恢复的。