文档章节

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

 独行侠
发布于 2016/04/14 16:08
字数 1258
阅读 61
收藏 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
eclipse控制台乱码的解决方法

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

霞女
2015/11/25
99
0
mac myeclipse console乱码

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

jinceon
2014/02/26
1K
1
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

没有更多内容

加载失败,请刷新页面

加载更多

ios多个target

1.建立3个target,分别为heroone,heroone test,heroone dev;分别为正式环境,test环境,dev环境 2.注意取消掉autocreate以防止名字不对,分别以Duplicate的方式建立另外两个scheme 3.创建...

HeroHY
今天
5
0
php获取客户端IP

php获取客户端IP 首先先阅读关于IP真实性安全的文章:如何正確的取得使用者 IP? 「任何從客戶端取得的資料都是不可信任的!」 HTTP_CLIENT_IP头是有的,但未成标准,不一定服务器都实现。 ...

DrChenXX
昨天
0
0
. The valid characters are defined in RFC 7230 and RFC 问题

通过这里的回答,我们可以知道: Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,添加了对于http头的验证。 具体来说,就是添加了些规则去限制HTTP头的规范性 参考这里 具体来说: org.apache.tom...

west_coast
昨天
1
0
刷leetcode第704题-二分查找

今天双十一买的算法书到货了,路上刷到有人说的这个题,借(chao)鉴(xi)一下别人的思路,这个是C++标准库里面的经典方法,思路精巧,优雅好品味 int search(int* nums, int numsSize, in...

锟斤拷烫烫烫
昨天
3
0
【分享实录】BANCOR算法详解及代码实现

1 活动基本信息 1)主题:【区块链技术工坊22期】BANCOR算法详解及代码实现 2)议题: BANCOR算法的特点和优劣势 BANCOR算法和举例 如何加入BANCOR.NETWORK交易所 如何开发自己的BANCOR去中心...

HiBlock
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部