文档章节

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

 独行侠
发布于 2016/04/14 16:08
字数 1258
阅读 49
收藏 0
点赞 1
评论 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

eclipse控制台乱码的解决方法

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

霞女 ⋅ 2015/11/25 ⋅ 0

mac myeclipse console乱码

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

jinceon ⋅ 2014/02/26 ⋅ 1

cmd命令行中logcat输出日志中文乱码

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

塔塔米 ⋅ 2014/01/30 ⋅ 0

DOS命令下使用sqlite3 命令中文乱码的解决办法

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

tianlonn ⋅ 2014/04/11 ⋅ 0

怎么设置koala的eclipse插件

@Koala考拉 你好,想跟你请教个问题:在console中显示出现乱码

草泥马二号 ⋅ 2014/10/30 ⋅ 3

phpstorm奇怪的问题?

告别了越来越臃肿的Eclipse,最近在学习使用JetBrains的IDE(如Intellij idea PhpStorm),感觉界面还是挺不错的,启动运行都很流畅。用惯了Eclipse,好多快捷键都不同了,稍微有点不习惯,但...

iman123 ⋅ 2013/12/20 ⋅ 3

在VScode中改变cmd的编码和字体

在node.js的调试过称中,经常需要在终端中使用console.log()输入一些变量,然而windows的cmd默认是GBK编码,在调试的过程中会出现乱码: 上面的图片中正常输出应该是“你好” 幸好VScode提供...

cloes ⋅ 2016/11/09 ⋅ 0

go语言 windows 32bit安装的常见问题

一:go get 命令的使用问题: 报的错误为: cd .; git clone https://github.com/nsf/gocode E:goPathsrcgithub.comnsfgoc odepackage github.com/nsf/gocode: exec: "git": executable file......

无与伦比的卒子 ⋅ 2012/11/06 ⋅ 0

在cmd窗口中显示UTF-8字符

有这么一个文件,它在Eclipse属性中看到是UTF8编码的,里面包含了中文: 但是当在Windows控制台中查看这个文件(为了方便,我将文件拷贝到桌面了)的时候,就是乱码了: C:Users002778Deskt...

独钓渔 ⋅ 2015/11/13 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

LVM

LVM: 硬盘划分分区成物理卷->物理卷组成卷组->卷组划分逻辑分区。 1.磁盘分区: fdisk /dev/sdb 划分几个主分区 输入t更改每个分区类型为8e(LVM) 使用partprobe生成分区的文件:如/dev/sd...

ZHENG-JY ⋅ 17分钟前 ⋅ 0

彻底删除Microsoft Office的方法

参照此链接彻底删除Office https://support.office.com/zh-cn/article/%e4%bb%8e-pc-%e5%8d%b8%e8%bd%bd-office-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8?ui=zh-CN&rs=zh-CN&ad=CN......

Kampfer ⋅ 32分钟前 ⋅ 0

大盘与个股之间关系

大盘走多:积极出手 顺势加码 大盘走空: 少量出手 退场观望 大盘做头:逆势减码 少量操作 大盘做底 : 小量建仓 小量试单

guozenhua ⋅ 34分钟前 ⋅ 0

Day16 LVM(逻辑卷管理)与磁盘故障小案例

lvm详解 简述 LVM的产生是因为传统的分区一旦分区好后就无法在线扩充空间,也存在一些工具能实现在线扩充空间但是还是会面临数据损坏的风险;传统的分区当分区空间不足时,一般的解决办法是再...

杉下 ⋅ 40分钟前 ⋅ 0

rsync实现多台linux服务器的文件同步

一、首先安装rsync,怎样安装都行,rpm,yum,还是你用源码安装都可以。因为我用的是阿里云的ESC,yum install rsync就ok了。 二、配置rsync服务 1.先建立个同步数据的帐号 123 groupadd r...

在下头真的很硬 ⋅ 53分钟前 ⋅ 0

前端基础(三):函数

字数:1685 阅读时间:5分钟 函数定义 在最新的ES规范中,声明函数有4中方法: -函数声明 -函数表达式 -构造函数Function -生成器函数 1.函数声明 语法: function name([param[, param2 [....

老司机带你撸代码 ⋅ 今天 ⋅ 0

Java虚拟机的Heap监狱

在Java虚拟机中,我是一个位高权重的大管家,他们都很怕我,尤其是那些Java 对象,我把他们圈到一个叫做Heap的“监狱”里,严格管理,生杀大权尽在掌握。 中国人把Stack翻译成“栈”,把Hea...

java高级架构牛人 ⋅ 今天 ⋅ 0

Spring MVC基本概念

只写Controller

颖伙虫 ⋅ 今天 ⋅ 0

微软重金收购GitHub的背后逻辑原来是这样的

全球最大的开发者社区GitHub网站花落谁家的问题已经敲定,微软最终以75亿美元迎娶了这位在外界看来无比“神秘”的小家碧玉。尽管此事已过去一些时日,但整个开发者世界,包括全球各地的开源社...

linux-tao ⋅ 今天 ⋅ 0

磁盘管理—逻辑卷lvm

4.10-4.12 lvm 操作流程: 磁盘分区-->创建物理卷-->划分为卷组-->划分成逻辑卷-->格式化、挂载-->扩容。 磁盘分区 注: 创建分区时需要更改其文件类型为lvm(代码8e) 分区 3 已设置为 Linu...

弓正 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部