• Windows上.java和.class文件字符集编码关系并包括C/C++上的类同分析


    【摘要】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字符集

    源文件字符集 编译后的二进制文件字符集
    GBK GBK
    UTF-8(带BOM) GBK
    UTF-8 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)保存,无法通过编译。

    .java文件字符集 .class文件字符集
    GBK UTF-8
    UTF-8(无BOM) UTF-8(但是中文已经乱码)
    UTF-8(有BOM) 编译失败无法生成.class文件


    针对上述的第二种情况,为什么.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 

  • 相关阅读:
    【BZOJ 3144】 [Hnoi2013]切糕
    【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏
    【BZOJ 4016】[FJOI2014]最短路径树问题
    【BZOJ 2152】 聪聪可可
    【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏 括号序列
    【BZOJ 3196】 Tyvj 1730 二逼平衡树 分块
    【BZOJ 2038】 [2009国家集训队]小Z的袜子(hose)
    【BZOJ 3196】 Tyvj 1730 二逼平衡树
    接下来的事
    【BZOJ 1189】 [HNOI2007]紧急疏散evacuate
  • 原文地址:https://www.cnblogs.com/ycloneal/p/5774304.html
Copyright © 2020-2023  润新知