5分钟课堂:输入输出汉字乱码的解决方法

createh53个月前 (02-01)技术教程17

从JDK 19升级到JDK 21和22之后,之前示例程序出现键盘输入的汉字在程序处理时乱码。
具体现象:只要是键盘输入的汉字,不管是输出还是保存到文件,汉字都是乱码,而程序中的汉字字符串常量的输出和保存则没有问题。

非UTF-8格式的源文件编译错解决办法

Windows系统往往默认保存文本文件(包括源代码文件)格式为ANSI/GBK。

JDK 21起全面使用UTF-8作为字符编码,带有汉字注释的源代码如果是ANSI格式,则编译会出错:

javac WriteFile.java

WriteFile.java:9: 错误: 编码 UTF8 的不可映射字符 (0xC3)
      // ?????д??????????????GBK
         ^
WriteFile.java:9: 错误: 编码 UTF8 的不可映射字符 (0xFC)
      // ?????д??????????????GBK
          ^
WriteFile.java:9: 错误: 编码 UTF8 的不可映射字符 (0xC1)
      // ?????д??????????????GBK

解决办法:编译时选择指定字符编码为GBK

javac -encoding GBK WriteFile.java

或者使用文本编辑器程序将源文件另存为UTF-8格式保存后,直接编译也没有问题。

控制台输入输出汉字乱码解决办法

使用如下代码测试,直接输出汉字字符串常量没有问题,初步分析应该是输入处理的问题。

FileWriter fw =  new FileWriter(file);
PrintWriter out = new PrintWriter(fw);
out.println("测试汉字输出 by CHEN");

原来程序的键盘输入语句为:

String s;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while ((s = in.readLine()) != null) {
        out.println(s);
}

输出的文件除了测试的内容汉字正常,其他键盘输入的内容乱码。分析原因应该是命令行窗口默认字符编码为GBK,为了避免乱码,需要在转换处理流这里指定字符集编码为GBK。

修改代码指定字符集GBK:

BufferedReader in = new BufferedReader(
              new InputStreamReader(System.in,"GBK"));

再次测试,文件内容可正常保存汉字。

附完整测试程序代码:

import java.io.*;

public class WriteFile {
  public static void main (String args[]) {
    // Create file
    File file = new File(args[0]);

    try {
      // 命令行窗口默认字符编码为GBK
      //为了避免乱码,需要在转换处理流这里指定字符集编码为GBK
      BufferedReader in = new BufferedReader(
        new InputStreamReader(System.in,"GBK"));   
      
      //默认输出文件编码为UTF-8
      FileWriter fw =  new FileWriter(file);
      PrintWriter out = new PrintWriter(fw);
      out.println("测试汉字输出 by CHEN");
      
      System.out.print("Enter file text.  ");
      System.out.println("[Type cntl-z to stop.]");

      String s;
			// Read each input line and echo it to the screen.
      while ((s = in.readLine()) != null) {
        out.println(s);
      }

      // Close the buffered reader and the file print writer.
      in.close();
      out.close();

    } catch (IOException e) {
      // Catch any IO exceptions.
      e.printStackTrace();
    }
  }
}

相关文章

IDEA中控制台输出是中文显示乱码(idea控制台中文输出是问号)

最近学习JAVA,作为一个新手小白,对编程的认知为0。跟随网上的教程学习,安装上IDEA工具后,每次输入语句中有中文时,只要执行就会显示乱码,太搞心态。问题如下图:作为小白,有问题肯定找度娘呀,可这次...

乱码是怎么产生的?一“文”打尽乱码问题

在我们处理文件或者处理程序字符时,时不时会遇到乱码的情况,而且这些乱码的情况让人很困惑,大多时候都是CV某度一下,看看有没有相关类似情况的博文出现,如果有那就按照博文上的方式一步一步去解决就好,如果没...

java安全编码指南之:异常处理(java安全编码规范考试题答案)

简介异常是java程序员无法避免的一个话题,我们会有JVM自己的异常也有应用程序的异常,对于不同的异常,我们的处理原则是不是一样的呢?一起来看看吧。异常简介先上个图,看一下常见的几个异常类型。所有的异...

eclipse怎么批量修改java文件编码使用操作流程

小伙伴们在使用eclipse时会批量修改java文件编码吗?小编今天带来的就是证明使用eclipse批量修改java文件编码的操作步骤,有需要的小伙伴可以来看看。首先你需要如下图所示打开eclipse...

JAVA 编码规范(java编码规范考试题答案)

1.背景1.1 愿景编码是一门艺术,优雅编码,规范编码,愿大家早日成为艺术大师。1.2 适用读者初中级程序员,参考编码的一些规范和建议。代码审批人员,审核代码时,一些参考的指标和方向。本文所举例的代码...

外国不用Java了?什么情况?(国外为什么不用健康码)

大家好,我是每天15点跟大家见面的播妞~黑马粉丝都知道,Java是黑马程序员的当家学科,播妞也一直很关注Java动态,但今天看到这样一个问题,直接把播妞看懵了:Java只有中国人在搞了吗????播妞第...