• 94-Java的转换流:解决代码与文件编码不一致读取乱码的问题


    转换流

    一、问题引入

    1、之前我们使用字符流读取中文是否有乱码?

    • 没有的,因为代码编码和文件编码都是UTF-8

    2、如果代码编码和文件编码不一致,使用字符流直接读取还能不乱码吗?

    • 会乱码
    • 文件编码和读取的编码必须一致才不会乱码

    二、范例

    使用相同编码读取不同编码的文件内容

    1、需求
    • 分别使用如下两种方式读取文件内容:

    • 1、代码编码是UTF-8,文件编码也是UTF-8,使用字符流读取观察输出的中文字符结果。

      package com.app.d4_transfer_stream;
      
      import java.io.BufferedReader;
      import java.io.FileReader;
      import java.io.Reader;
      
      /**
       * 目标:分别使用如下方式读取文件内容:
       *      1、代码编码:UTF-8,文件编码:UTF-8,使用字符流读取
       *      2、代码编码:UTF-8,文件编码:GBK,使用字符流读取
       */
      public class CharSetTest01 {
          public static void main(String[] args) {
              try (
                      // 1、定义一个字符输入流管道与源文件接通
                      Reader fr = new FileReader("day11-io2-app/src/data02.txt");
      
                      // 2、把字符输入流包装成一个字符缓冲输入流管道
                      BufferedReader br = new BufferedReader(fr);
                      ) {
      
                  // 3、按照行读取数据
                  String line;
                  while ( (line = br.readLine()) != null ) {
                      System.out.println(line);
                  }
      
              }catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      
      abc我爱你中国
      abc我爱你中国
      abc我爱你中国
      abc我爱你中国
      abc我爱你中国
      
         abc我爱你中国
      
      Process finished with exit code 0
      
      


    • 2、代码编码是UTF-8,文件编码使用GBK,使用字符流读取观察输出的中文字符结果。

      • 随便在某个盘中创建一个GBK类型的文本文件

        在这里插入图片描述


        在这里插入图片描述


        在这里插入图片描述


      package com.app.d4_transfer_stream;
      
      import java.io.BufferedReader;
      import java.io.FileReader;
      import java.io.Reader;
      
      /**
       * 目标:分别使用如下方式读取文件内容:
       *      1、代码编码:UTF-8,文件编码:UTF-8,使用字符流读取
       *      2、代码编码:UTF-8,文件编码:GBK,使用字符流读取
       */
      public class CharSetTest01 {
          public static void main(String[] args) {
              try (
                      // 1、定义一个字符输入流管道与源文件接通
                      Reader fr = new FileReader("E:/JavaDevelop/FileDemo02/data.txt");
      
                      // 2、把字符输入流包装成一个字符缓冲输入流管道
                      BufferedReader br = new BufferedReader(fr);
      
                      ) {
      
                  // 3、按照行读取数据
                  String line;
                  while ( (line = br.readLine()) != null ) {
                      System.out.println(line);
                  }
      
              }catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      
      abc�Ұ����й�
      abc�Ұ����й�
      abc�Ұ����й�
      abc�Ұ����й�
      abc�Ұ����й�
      
         abc�Ұ����й�
      
      Process finished with exit code 0
      
      

    总结

    1、字符流直接读取文本内容为什么会出现乱码?

    • 因为文件和代码编码不一致导致读取到的数据出现中文乱码
    • 文件和代码编码必须一致才不会出现中文乱码


    三、字符转换流

    1、字符输入转换流:IuputStreamReader
    • 可以把原始的字节流按照指定编码转换成字符输入流。

    如何解决字符输入流文件和代码编码不一致出现中文乱码的情况?

    • 使用字符输入转换流
      • 可以提取文件(GBK)的原始字节流,原始字节不会存在问题
      • 然后把字节流以指定编码转换成字符输入流,这样字符输入流中的字符就不乱码了

    在这里插入图片描述


    (1)构造器
    构造器说明
    public InputStreamReader(InputStream is)可以把原始的字节流按照代码默认编码转换成字符输入流。
    几乎不用,与默认的FileReader一样
    public InputStreamReader(InputStream is, String charsetName)可以把原始的字节流按照指定编码转换成字符输入流,
    这样字符流中的字符就不乱码了(重点
    package com.app.d4_transfer_stream;
    
    import java.io.*;
    
    /**
     * 目标:解决代码编码是UTF-8与文件编码是GBK的中文乱码问题
     */
    public class InputStreamReaderDemo02 {
        public static void main(String[] args) {
            try (
                    // 1、提取GBK文件的原始字节流
                    InputStream is = new FileInputStream("E:/JavaDevelop/FileDemo02/data.txt");
    
                    // 2、把原始字节流转换成字符输入流
                    // Reader isr = new InputStreamReader(is); //  默认以UTF-8编码转换成字符流。还是会出现中文乱码问题,跟直接使用FileReader是一样的
                    Reader isr = new InputStreamReader(is, "GBK");  // 以指定的GBK编码转换成字符输入流,可以解决乱码问题
    
                    // 3、把字符输入流包装成一个字符缓冲输入流管道
                    BufferedReader br = new BufferedReader(isr);
    
            ) {
    
                // 3、按照行读取数据
                String line;
                while ( (line = br.readLine()) != null ) {
                    System.out.println(line);
                }
    
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    abc我爱你中国
    abc我爱你中国
    abc我爱你中国
    abc我爱你中国
    abc我爱你中国
    
       abc我爱你中国
    
    Process finished with exit code 0
    
    


    总结

    1、字符输入转换流 InputStreamReader 作用是啥?

    • 可以解决字符流读取不同编码出现中文乱码的问题
    • 可以指定编码把原始字节流转换成字符流,如此字符流中的字符不会出现乱码问题



    2、字符输出转换流:OutputStreamWriter
    • 可以把字节输出流按照指定编码转换成字符输出流。

    如果需要控制写出去的字符使用的编码,怎么办?

    • 可以把字符以指定编码获取字节后再使用字节输出流写出去:
      • “我爱你中国”.getBytes(“指定编码”);
    • 也可以使用字符输出转换流实现(重点

    在这里插入图片描述


    (1)构造器
    构造器说明
    public OutputStreamWriter(OutputStream os)可以把原始的字节输出流按照代码默认编码转换成字符输出流。
    几乎不用
    public OutputStreamWriter(OutputStream os, String charsetName)可以把原始的字节输出流按照指定编码转换成字符输出流。
    重点
    package com.app.d4_transfer_stream;
    
    import java.io.*;
    
    /**
     * 目标:学会字节输出流转换成字符输出流,指定编码后,再包装成字符缓冲输出流,输出数据。
     */
    public class OutputStreamWriterDemo03 {
        public static void main(String[] args) {
            try (
    
                    // 1、定义一个字节输出流
                    OutputStream os = new FileOutputStream("day11-io2-app/src/out03.txt");
    
                    // 2、把原始的字节输出流转换成字符输出流
                    // Writer osw = new OutputStreamWriter(os); // 以默认的UTF-8编码写字符出去。跟直接使用FileWriter一样的
                    Writer osw = new OutputStreamWriter(os, "GBK"); // 指定GBK编码写字符出去。
    
                    // 3、将字符输出流包装成字符缓冲输出流
                    BufferedWriter bw = new BufferedWriter(osw);
    
                    ) {
    
                    bw.write("abc我爱你中国!!123");
                    bw.write("abc我爱你中国!!123");
                    bw.newLine();   // 换行
                    bw.write("abc我爱你中国!!123");
    
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    在这里插入图片描述




    总结

    1、字符输出转换流 OutputStreamWriter 的作用是啥?

    • 可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码
  • 相关阅读:
    ClickHouse进阶(十三):Clickhouse数据字典-3-文件数据源及Mysql数据源
    为了学明白中断机制,我努力了
    无主复制系统(2)-读写quorum
    pytorch中对nn.BatchNorm2d()函数的理解
    C#开发的股票盯盘小工具——摸鱼助手,附源码
    异步编程详解(.NET)
    【RtpSeqNumOnlyRefFinder】webrtc m98: ManageFrameInternal 的帧决策过程分析
    docker入门教程
    如何认识python
    操作系统笔记(王道考研) 第三章:内存管理
  • 原文地址:https://blog.csdn.net/yelitoudu/article/details/127109708