先列几个概念:
1.各种字节IO流(ByteArrayOutputStream,FileOutputStream)都是继承的InputStream,和OutputStream。
2.内存中运行的各种对象的字节编码格式都是Unicode
3.我们将字符串(String)转为字节数组(Byte[]),或者将字节数组转化为字符串的时候,可以指定编码格式,常见的编码格式有UTF-8,GBK,Unicode,ISO-8859等。
举例:
String str ="";
str.getBytes("UTF-8")
byte[] buffer =newbyte[256];
ByteArrayOutputStream out=newByteArrayOutputStream();
out.write(buffer,0, n)
out.toString("GBK")
第一段代码我们将字符串编码格式为UTF-8的字节数组。
第二段代码我们将字节数组写入字节流输出对象中,并使用toString转化为字符串,这个时候的转换我们使用了GBK格式编码。
如果我们不指定编码格式,则JVM会使用系统默认的编码格式进行编码和解码(Android Studio,eclipse等默认GBK、或者UTF-8,可以修改配置成需要的编码格式)。
我们知道,汉字在UTF-8中是编码为3个字节的,而在GBK中是编码成两个字节的。
如果编码的时候,使用的UTF-8,解码使用GBK,就会出现乱码。
举个例子
字符串 "广州",被编码成UTF-8格式的话是6个字节
E5 B9 BF E5 B7 9E
前三个字节表示"广",后三个字节表示"州"
如果这个字节数组被GBK格式解码后,就会每两个字节对应一个汉字
E5 B9 --> 骞
BF E5--> 垮
B7 9E--> 窞
"广州" 就变成了乱码 "骞垮窞"
解决方法:
所以,我们在字符串的编码解码过程中(主要是IO通信时候),最好是主动指定编码的格式,设置成同意的格式,不然的话,如果编码所在机器和解码服务器的默认编码格式不一样的话,就很容易出现乱码。