您的位置:首页 > 编程语言 > Java开发

从内存角度解析Java字符编码

2016-07-16 12:12 567 查看
参考大神链接:http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/

关于ASCII,GB2312,GBK,单字节编码,多字节字符集,字节编码,字符集,代码页,码表等概念,参见这篇文章:

Java为什么选择unicode字符集?字符编码的那些事

Situation:

         编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换较多。

Complication

         如何才能更好的理解Java中的编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换较多。编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换较多。内码(internal encoding)和外码(external encoding),理解在Java中字符只以一种形式存在,那就是unicode呢?

SubJect

本文将以JavaIO中存在的编码为例,从内存角度对Java编码进行解析

1. 使用FileReader读取GBK文件(中文操作系统下默认编码方式是GBK)

(1)代码如下(a.txt是GBK编码的文本文件)

public static void main(String[] args)throws IOException {
FileReader fr = new FileReader("C:\\a.txt");
char[] chs = new char[16];
int length = 0;

while((length = fr.read(chs))!=-1){
System.out.print(String.valueOf(chs,0,length));
}
}

(2)内存图解(以I am 君山这句话为例)



(3)工作原理

在将文本从外部文件读入内存中时,存储到内存中byte[]中。在JVM中、在内存中、在代码里声明的每一个char、String类型的变量中字符以unicode格式存在。

 如果你在eclipse将java文件properties的默认编码方式有GBK改为UTF-8,就会乱码。因为你使用UTF-8来解码GBK编码的字节流。具体原理分析见2.

2. 使用FileReader读取UTF-8文件

(1)      代码如下(a.txt是UTF-8编码的文本文件)

public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("C:\\a.txt");
char[] chs = new char[16];
int length = 0;

while((length = fr.read(chs))!=-1){
System.out.print(String.valueOf(chs,0,length));
}
}

(2)内存图解(以I am 君山这句话为例)



(3)      工作原理

结果是 I am 鍚涘北

造成乱码的原因就是因为使用了错误的字符编码去解码字节流。字符文本是UTF-8编码的字节流,用unicode字符集,但是采用默认的GBK的字符编码,即用GBK来解码UTF-8编码的字节流。

实际上在内存中存储的用unicode编码的结果就是错的。

有两种解决方案:

1. 将系统的默认编码方式改为UTF-8,这样就使用正确的字符编码来解码了。



2. 采用下面3的方式,使用转换流,指定解码的码表。无论你的默认编码方式是什么,都可以获得正确的输出。因为在内存中你存了正确的unicode编码的字节序列。

3. 使用InputStreamReader读取UTF-8文件

(1)      代码如下(a.txt是UTF-8编码的文本文件)

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\a.txt"), "UTF-8"));
String line = null;
while ((line=br.readLine())!=null) {
System.out.println(line);
}
br.close();
}

(2)内存图解(以I am 君山这句话为例)



(3)   工作原理

    在将文本从外部文件读入内存中时,存储到内存中byte[]中。在JVM中、在内存中、在代码里声明的每一个char、String类型的变量中字符以unicode格式存在。与第二种情况不同的是,指定了字符编码的码表是UTF-8,与文本文件编码的方式是相同的,从而保证在内存中存储的unicode编码的字节是正确的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: