Windows上.java和.class文件字符集编码关系并包括C/C++上的类同分析
2016-08-23 17:49
316 查看
【摘要】Windows系统默认采用GBK字符集,因此导致无法使用UTF-8解码。本文在首先说明Windows上使用的字符集,后分析了JAVA下.java、.class、javac之间的字符集关系,以及分析了VS的C/C++项目的源文件、二进制文件与编译器间的字符集关系。最后总结:在javac的使用中,最好采用-encoding参数指明.java文件使用的字符集,以免造成不可恢复的中文乱码。
【问题重现】
JAVA项目中,由于源文件存储采用不同的字符集导致项目输出乱码。当采用GBK存储源文件,正常符出”中文“,而采用UTF-8存储源文件,却输出乱码。
下图为采用UTF-8存储源文件,却输出乱码:
下图为采用GBK存储源文件,正常输出:
【一、Windows系统默认字符集】
1980年,中国制定了GB2310-80,一共收录了7445个字符。1993年,Unicode 1.1版本推出,收录20902个汉字,中国制定了等同于Unicode 1.1版本的“GB 13000.1-93”,简称为GB13000。微软对GB2312-80扩展,并收录了GB13000和Unicode1.1之中的汉字,制定了GBK编码。在Windows中使用代码页CP936表示。如下图,在控制台中使用chcp命令可以查看Windows使用的字符集。
GBK是Windows中文系统默认的字符集。
【二、VS下C/C++项目源文件、二进制文与编译器的关系】
笔者使用的VC编译器版本是19.00.24210,使用的VS版本的VS2015。
众所周知,每个文件保存时都会选择指定的字符集,即源文件在Windows上的保存时使用的字符集可以选择GBK和UTF-8形式,在中文的Windows 7系统上,VS默认存储源文件的字符集是GBK。
使用VC编译器编译成二进制可执行文件后,二进制文件所使用的字符集符合以下表格。其中带BOM的UTF8表示在文件开头使用三个字符作为BOM头,标识文件采用的是UTF8字符集。
【三、JAVA下.java、.class、JVM、输出控制台之间的关系】
在阿里,许多人使用intellij idea作为IDE开发JAVA应用,而intellij idea默认使用UTF8字符集,如下图,IDE Encoding表示整个IDE使用UTF8编码,Project Encoding表示本项目使用UTF8编码。
JAVA下,.java文件和.class文件的字符集关系如下表,比如对于.java中的“中文”字符串str,.class中的字符串有三种情况:①.java以GBK格式保存,即str以GBK格式保存内容“中文”,经过javac编译后,.class中str变为UTF-8保存的"中文“;②.java以UTF-8(无BOM)保存,即str以UTF-8保存内容”中文“,经过javac编译后,.class中str变为UTF-8保存的"涓枃",变为乱码;③.java以UTF-8(有BOM)保存,无法通过编译。
针对上述的第二种情况,为什么.class保存了UTF-8的乱码呢?这是由于.class一定是使用unicode字符集,即兼容UTF8,而.java可以使用任意字符集。JAVA的生成过程使用字符集如下:”.java(任意编码) —> .class(Unicode) —> JVM内(Unicode)“。生成乱码是由于javac把UTF8格式的.java文件当成了GBK格式,因为javac中可以通过-encoding指定.java的字符集,而没有指定的情况将默认.java为系统采用字符集。由于没有使用-encoding,javac将已经是UTF-8的.java文件当成GBK文件处理,从而导致乱码。具体可见:https://www.zhihu.com/question/30977092
【问题重现】
JAVA项目中,由于源文件存储采用不同的字符集导致项目输出乱码。当采用GBK存储源文件,正常符出”中文“,而采用UTF-8存储源文件,却输出乱码。
下图为采用UTF-8存储源文件,却输出乱码:
下图为采用GBK存储源文件,正常输出:
【一、Windows系统默认字符集】
1980年,中国制定了GB2310-80,一共收录了7445个字符。1993年,Unicode 1.1版本推出,收录20902个汉字,中国制定了等同于Unicode 1.1版本的“GB 13000.1-93”,简称为GB13000。微软对GB2312-80扩展,并收录了GB13000和Unicode1.1之中的汉字,制定了GBK编码。在Windows中使用代码页CP936表示。如下图,在控制台中使用chcp命令可以查看Windows使用的字符集。
GBK是Windows中文系统默认的字符集。
【二、VS下C/C++项目源文件、二进制文与编译器的关系】
笔者使用的VC编译器版本是19.00.24210,使用的VS版本的VS2015。
众所周知,每个文件保存时都会选择指定的字符集,即源文件在Windows上的保存时使用的字符集可以选择GBK和UTF-8形式,在中文的Windows 7系统上,VS默认存储源文件的字符集是GBK。
使用VC编译器编译成二进制可执行文件后,二进制文件所使用的字符集符合以下表格。其中带BOM的UTF8表示在文件开头使用三个字符作为BOM头,标识文件采用的是UTF8字符集。
源文件字符集 | 编译后的二进制文件字符集 |
GBK | GBK |
UTF-8(带BOM) | GBK |
UTF-8 | UTF8 |
在阿里,许多人使用intellij idea作为IDE开发JAVA应用,而intellij idea默认使用UTF8字符集,如下图,IDE Encoding表示整个IDE使用UTF8编码,Project Encoding表示本项目使用UTF8编码。
JAVA下,.java文件和.class文件的字符集关系如下表,比如对于.java中的“中文”字符串str,.class中的字符串有三种情况:①.java以GBK格式保存,即str以GBK格式保存内容“中文”,经过javac编译后,.class中str变为UTF-8保存的"中文“;②.java以UTF-8(无BOM)保存,即str以UTF-8保存内容”中文“,经过javac编译后,.class中str变为UTF-8保存的"涓枃",变为乱码;③.java以UTF-8(有BOM)保存,无法通过编译。
.java文件字符集 | .class文件字符集 |
GBK | UTF-8 |
UTF-8(无BOM) | UTF-8(但是中文已经乱码) |
UTF-8(有BOM) | 编译失败无法生成.class文件 |
相关文章推荐
- Java中的字符集编码入门(四)网页文件的编码
- 实例分析Java Class的文件结构
- 通过阅读、分析和翻译二进制格式的Java Class文件学习Java Class的技术
- 对android应用安装程序apk反编译与分析(二)-jad将class文件转化为java文件
- JAVA文件操作之默认字符集编码
- C++ UTF-8编码识别(分析文件内容,非文件头)
- windows java读取utf-8编码文件时出现第一个字符为未知字符"?" 的解决方案
- 实例分析Java Class的文件结构
- 读取某一目录下(包括子目录)所有mp3、wma、m4a格式文件,制作成m3u列表(Java, Windows)
- Java 基础面试 每日一点Java源文件(*.java)——>Java编译器——>字节码文件(*.class)——>类装载器——>字节码校检器—— >解释器——>操作系统(Windows、Linux
- JVM学习序列之一:Java Class文件结构分析
- Java源文件和.class文件的对应关系
- 实例分析Java Class的文件结构
- 实例分析Java Class的文件结构
- JVM学习序列之一:Java Class文件结构分析
- 实例分析Java Class的文件结构
- 实例分析 Java Class 的文件结构
- java class文件内容分析
- java程序 一次改变指定目录下所有文件编码(包括子目录中的文件)
- Java 的class文件关系