Java 编码那些事(二)

Java中有哪些编码

建议首先阅读Java 编码那些事(一)

上一篇文章中,说到了编码的分类。现在说说java中的实际运用。在使用tomcat的时候,绝大部分同学都会遇到乱码的问题,查查文档,google一下解决方案啥的,都是设置这里,设置那里,或者在代码中添加编码方式,虽然最终问题解决了,但是你真的知道这是什么意思么?

在平时开发Java的时候,我们会遇到很多编码设置,其中包括:

  • Java文件的编码:Java文件的编码表示编写代码得时候,.java文件本身的编码,这个编码的影响在于将你的写的代码源文件复制一份,使用其他编辑器打开,若两个编辑器的默认编码方式不一样,则打开源文件就会变成乱码。一般英文的影响不大,因为大多数编码都兼容ASCII编码,但是中文要是编码不正确,则会乱码。

    IDEA的设置在:Setting->Editor->File Encodings中设置

  • JVM编码:JVM编码表示JVM在读取String类型的默认编码,可以使用Charset.defaultCharset().name() 获取。可以在JVM启动参数中使用-Dfile.encoding=UTF-8进行设置。

一般需要区分的就是这两种编码。下面着重说下JVM编码的体现。

字节流与字符流

熟悉IO的同学应该都明白这两个流的区别。一般会出现字符乱码都在于需要与其他程序进行IO的时候。

先看看使用字节流进行读取文件的时候:

    public static void main(String[] args){
        String path="G:\\test.txt";

        try(BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream(path))) {
            for (byte bytes[] = new byte[1024]; inputStream.read(bytes) != -1; ) {
                String context = new String(bytes);
                System.out.println(context);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

然后再G盘新建一个文本文件,输入一段文字。使用默认的格式保存。

可以查看输出:

�����ļ��ļ�                                                                         

乱码了,下面来分析一下:

首先这里是JVM运行时的编码,因此和JVM的编码设置有关。打印JVM目前的编码设置:

System.out.println(Charset.defaultCharset().name());
输出:UTF-8

找到刚刚新建的文件test.txt,点击另存为,可以发现默认编码为ANSI,前一篇文章中说过,ANSI作为windows系统中的特殊存在,它在简体中文编码的情况下默认为GBK编码。这便是乱码的原因,解决方案有两种:

  1. 设置JVM启动项:-Dfile.encoding=GB2312
  2. 在编码byte数组的时候,指定GB2312编码:String context = new String(bytes,"GB2312");

这里推荐第二种,毕竟UTF8更加通用

问题完美解决。

同理,网络IO也能通过以下方法解决。

看明白了上面的发现问题和解决问题的流程的同学,下次遇到文件编码的问题,结合上一篇文章对编码的讲解,详细应该能够独立解决问题。