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 的作用是啥?

  • 可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值