文档章节

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

 独行侠
发布于 2016/04/14 16:08
字数 1258
阅读 54
收藏 0

   乱码的出现,通常是由于我们使用了错误的charset或者与平台相关的charset引起的,java是跨平台的,如果你指定了正确的,或者特定的某种编码,那么在任何时候,它都不会出现我们所不期望的乱码.

在java的io的操作过程中,包括System.out简单输出信息,都是依赖于我们所设置的charset或者默认charset(如果不设置)。

获得系统默认的charset:

import java.nio.charset.Charset;
public class HelloWorld{    
    public static void main(String[]args){
    
                System.out.println("DefaultCharset="+Charset.defaultCharset().name());
                Console console=System.console();
                Field fieldOut=console.getClass().getDeclaredField("out");
                fieldOut.setAccessible(true);
                Object streamEncoder=fieldOut.get(console);
                Field fieldCS=streamEncoder.getClass().getDeclaredField("cs");
                fieldCS.setAccessible(true);
                Charset consoleCharset=(Charset)fieldCS.get(streamEncoder);
                System.out.println("ConsoleCharset="+consoleCharset.name());//x-mswin-936
               System.out.println("===========");
               System.out.println(Charset.defaultCharset().name());
               String chineseChar="汉";
               System.out.println(chineseChar);
    }
}


上面代码的输出在我的电脑上是(java HelloWorld):

DefaultCharset=GBK
ConsoleCharset=x-mswin-936
===========
GBK


说明:ConsoleCharset=x-mswin-936  这种charset是microsoft的中文系统的一种编码了,兼容GBK,所以我们可以认为其就是GBK


数据转换及输出过程解析:

汉(unicode是java在内存中的数据格式)---编码(DefaultCharset=GBK)为二进制--->二进制数据传递----解码(ConsoleCharset=x-mswin-936)-->显示

在这个过程中,有一个编码(encode)的步骤和一个解码(decode)的过程,如果这两个charset不一致,或者不兼容,那么乱码必然出现.


测试方式如下(即更改DefaultCharset为UTF-8,使DefaultCharset与ConsoleCharset不兼容,不一致)

java -Dfile.encoding=UTF-8  HelloWorld

输出为:

DefaultCharset=UTF-8
consoleCharset=x-mswin-936(注:此编码可等同于GBK)
===========
UTF-8
姹 (注:此处为乱码)


好了,乱码就这样子产生了.


回到eclipse我们也可以做类似的测试,不过代码要稍微改一下,因为eclipse的console与xp下面模拟dos的console是不一样的。

上面与Console对象有关的代码不可用。代码如下:


import java.nio.charset.Charset;

public class HelloWorld {
    public static void main(String[] args) {
    System.out.println("DefaultCharset="+Charset.defaultCharset().name());
    String chineseChar="汉";
    System.out.println(chineseChar);
    }
}
输出为:

DefaultCharset=GBK

可能有一些人测试会输出乱码,后面将测试和说明.

eclipse也有console,那么它的console的编码在哪改呢?


就在这个HelloWorld上右键Run As->Run Configuration->Java Application->New->Common->Encoding 即为这个编码了。

我们改为UTF-8再运行上面的代码,输出为:

DefaultCharset=UTF-8

这个地方有点迷惑人的是,当你修改了eclipse的console的Encoding的时候,它在运行一个java application的时候,把Default也改成一样的了

这样子,肯定是不会有乱码的,除非你最初的数据已经是乱码了.

我们可以在Run As->Run Configuration->Java Application上面New的那个选项下的Arguments->VM arguments     输入-Dfile.encoding=GBK


再运行上面的代码,输出将是:

DefaultCharset=GBK
��(乱码)

这下子,如愿以偿的,乱码出现了。

eclipse的console的encoding与xp下dos窗口的作用类似,只是一个输出,它们都有属于自己的编码

在eclipse下如果更改了console的encoding(默认是与项目的编码一致),那么你所运行的这个程序的DefaultCharset也会被更改成与其一致的编码,除非你在vm arguments加入类似-Dfile.encoding=GBK

汉(unicode )---编码(DefaultCharset)为二进制--->二进制数据传递----解码(ConsoleCharset=x-mswin-936)-->console显示


如果对console直接写入字节数组,这个将"汉"字变为数组的过程就是上面的编码过程,而如果我们直接将这个数组写入console,可以同样解决上面的code出现的乱码问题(DefaultCharset=GBK,Console Encoding=UTF-8)

public class HelloWorld {
    public static void main(String[] args) {
    System.out.println("DefaultCharset="+Charset.defaultCharset().name());
    String chineseChar="汉";

  System.out.println(chineseChar);
    System.out.write(chineseChar.getBytes("UTF-8"));

//或者另外的一种写法如下:

    OutputStreamWriter os=new OutputStreamWriter(System.out, "UTF-8");//指定了encode过程中使用的编码
    os.write(chineseChar);
    os.flush();
    }
}

以上代码中,在直接输出乱码的情况下,而后面两种处理方式都可以正确的输出"汉"字

 

在eclipse中运行的程序,如果DefaultCharset 与Console的编码是一致的,并且是可以对你要输出的字符进行编码(对中文,UTF-8和GBK),那么一个字符串是可以直接被输出到Eclipse Console的,如果是乱码,那么也就是说明,保存在String里面的字符已经是乱码或者不是unicode编码的字符串。此时,要分析原字符的乱码产生原因,而不是一味的在System.out进行输出的时候,用各种charset进行试探性输出.



小结:

所有的数据都要依据某种编码转换为二进制存储,传输,再进行解码显示。如果这两个过程所用的charset不一致,就将可能出现乱码(如果是编码兼容,是不会的,如果不兼容,肯定会出现).


下一节,进行文件操作,并进行编码解码的问题,并对与汉字相关的几种编码进行简单的说明。







© 著作权归作者所有

共有 人打赏支持
粉丝 1
博文 19
码字总数 9797
作品 0
成都
DOS命令的一些技巧总结(大纲)

1.设置dos启动的默认路径 安全模式登录(开机启动按F8),依次右键单击我的电脑--管理--本地用户和组-用户--administrator--配置文件--本地路径--输入“C:WINDOWSsystem32”,这样我们就能使...

述而不作
2012/02/29
0
0
mac myeclipse console乱码

现象一:直接执行tomcat的startup.sh,日志里无乱码,正常显示中文。 现象二:在Myeclipse里以java application方式执行文件,console打印出来的中文也是正常的。 现象三,即问题: 在myecl...

jinceon
2014/02/26
1K
1
eclipse控制台乱码的解决方法

乱码!Eclipse 的控制台console必须用GBK编码。 Eclipse 的控制台必须用GBK编码。所以条件1和条件4必须同时满足否则运行的还是乱码。才能保证不是乱码。 条件1,Window | Preferences | Work...

霞女
2015/11/25
99
0
cmd命令行中logcat输出日志中文乱码

http://www.6san.com/913/ 在命令行使用adb logcat命令直接输出日志中文内容显示乱码,原因是中文系统中cmd命令行窗口默认的编码是GBK,而LogCat打印的日志是UTF-8编码,所以adb logcat命令输...

塔塔米
2014/01/30
0
0
DOS命令下使用sqlite3 命令中文乱码的解决办法

1、退出dos 或者重新开启在CMD窗口,输下:chcp 65001 然后回车确定 注意 65001 是Unicode (UTF-8) 65001 的编码设置,Chinese Simplified (GB2312) 的设置为936 ,可以从EditPlus 工具的菜单...

tianlonn
2014/04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一步步编写自己的PHP爬取代理IP项目(二)

这一章节我们正式开展我们的爬虫项目,首先我们先要知道哪个网站能获取到免费代理IP,目前比较火的有西刺代理,快代理等,这里我们拿西刺代理作为例子。 这里就是一个个免费的IP地址以及各自...

NateHuang
25分钟前
1
0
11-利用思维导图梳理JavaSE-Java的反射机制

11-利用思维导图梳理JavaSE-Java的反射机制 主要内容 1.反射与Class类 1.1.反射概念 1.2.Class类 1.3.实例化Class类 1.4.反射的作用 1.5.Class对象的作用 2.反射的深入应用 2.1.调用无参的成...

飞鱼说编程
31分钟前
1
0
How to serve the world from home computer?

最近在开发web应用,很想知道,通过公网来访问,效果会不会好。今天在做家务的时候,突然想到,如果我自己写一个ip转发的工具,不就可以实现了吗?但是转过头一想,这么大众的想法,怎么会没...

pearma
47分钟前
1
0
今天在码云遇到一个很有意思的人 for Per.js

今天在码云遇到一个很有意思的人,他在我的Per.js项目下面评论了一句,大意为“你试试这句代码,看看速度到底是你快还是Vue快”【当然,这个评论被我手残不小心删掉了...】。 然后我就试了,...

Skyogo
今天
50
0
Java -------- 首字母相关排序总结

Java 字符串数组首字母排序 字符串数组按首字母排序:(区分大小写) String[] strings = new String[]{"ba","aa","CC","Ba","DD","ee","dd"}; Arrays.sort(strings); for (int i ...

切切歆语
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部