乱码之一 eclipse console 和 xp console 乱码 全程详解(三)

先简单的对我在第一部分提到的三种编码说明一下:

1)iso8859-1,单字节的编码,在0-255之间的字节.

2)gbk 汉字内码扩展规范,兼容gb2312是一种双字节编码。即对于每个字符,都用两个字节来表示。

3)utf-8  是UNICODE的一种变长字符编码又称万国码。

iso8859-1是单字节编码,但是对于超过0-255的不能编码
unicode是一种定长双字节编码,是一种国际通用编码,但是其缺点是,即使是对于一个字母或者一个简单的数据,也要用一个双字节,比较的浪费空间
而utf-8是一种变长编码,即将unicode的值分为多部分,并按照每个部分按照一定的模板转为多个字节,形成utf-8,所以汉字也可以保存为utf-8

gbk是一个内码,在国际化编码中,是尽量不使用的.

尽管汉字不能直接转为iso8859-1但是,我们可以先将汉字转为utf-8(通常是三字节)然后可以再转为iso8859-1,这样子是没有问题的

以上三个的转换关系,尤其是uicode,utf-8之间的转换,网上有很多资料可以查.

中文可以被保存并传输,而不丢失数据的编码就是我们常见的(UTF系列我统称为UTF-8)和GBK了,所以对于一个有中文存在(java  code source file中有中文)的项目,通常使用这两种编码,而且最好是使用UTF-8

当一个项目使用了某种charset的时候,eclipse保存的java code source file 是以这种编码保存的,然后在编译的时候也是用这种编码保存的。所以推荐大家通常项目编码使用UTF-8

下面再代码说明一下读写中文的编码解码问题:

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class WriteFile {
    public static void main(String[] args) throws Exception{
        String chineseChar="汉";
        FileOutputStream fs=new FileOutputStream("d:\\utf8.txt");
        OutputStreamWriter ow=new OutputStreamWriter(fs, "UTF-8");
        ow.write(chineseChar);
        ow.flush();
        ow.close();
    }
}

代码说明:将"汉"以UTF-8编码并保存到utf8.txt这个文件中。(保存之后,可以用十六进制软件打开看到,数据与在第一部分所说的编码是一致的,即里面                      的数据是"汉"的UTF-8编码)

                 你也可以将上面的编码改为GBK,运行程序,保存数据,用十六进制软件打开也是正确的(里面的数据是“汉”的GBK编码)

读文件:


import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class ReadFile {
    public static void main(String[] args) throws Exception{
        FileInputStream fs=new FileInputStream("d:\\utf8.txt");
        InputStreamReader ir=new InputStreamReader(fs, "UTF-8");
        BufferedReader br=new BufferedReader(ir);
        String str=br.readLine();
        System.out.println(str);
    }

}

上面的charset为UTF-8,即使用UTF-8对读入的数据进行解码,之后再将其转为unicode存入内存,变量 str指向它.

如果上面读取的文件保存时选择的编码不是UTF-8(比如将上面写文件时编码设置为gbk),则在console输出时,即会出现乱码.

这个过程

"汉"(unicode)--编码并写文件(encode)-->文件--读取并解码(decode)-->字符串(unicode)

在encode与decode时的charset如果不一致时就出现乱码,在两段代码中,如果不指定charset那么java将使用DefaultCharset,就有可能出现乱码



乱码的一个简单的检测办法:

因为java在内在中保存的字符串,都是unicode编码的,所以如果一个String显示的正确的,那么其toCharArray方法得到的char的int值,是一个unicode,可以在网上找一下,这个unicode对应的字符,肯定是显示的那个字符。

如果一个String的unicode不对,那么要想正确的显示出来,则肯定要进行转码,才能输出到console(这里我没有提到console的编码了,当然了,肯定是与unicode编码一致的encoding,一般是utf-8了)。


一个字符串,是这样子生成的

1)从char[]chs,使用new String(chs)生成,;此时java就是假设这个char[]chs是一个unicode的。

比如我们常见的人民币符号¥,其对应的unicode是0xA5,转为十进制就是165,char[]chs=new char[]{165};System.out.println(new String(chs));

就可以输出¥了.

2)更常见的方式是,从外部获得的数据,然后转为字符串,再显示,这个时候,其转换格式则是:

binary---DefaultCharset(encoding)--->String---DefaultCharset(decoding)--->binary----Eclipse Console Charset(encoding)--->显示


除非你在读取外部资源,比如数据库,网络,文件的时候指定了格式。


即:如果一个字符串,其在内存中的unicode如果是正确的,要保证defaultCharset和EclipseConsole一致,并且对于你要显示的字符是兼容的,才不会出现乱码.


转载于:https://my.oschina.net/u/186769/blog/659506

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值