JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter

1.由乱码引出的问题

1.字符流在处理文本文件时比较方便,且对文本文件的读写效率要高;
2.在读取文件的时候,如果文件的格式和读入流的格式不一致,则会导致读入的内容乱码
下面,我们通过一个例子来观察一下这个问题:
(以下操作在windows上进行)
1.1 另存为文件的格式为 GBK
【JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter】文件 : D:\EDailyRoutine\java-io-test\\字符读取乱码演示.txt
另存为一下,选择编码格式为 GB2312.
文件内容中包含中文,内容如下:
hello FileInputReader
你好,这里演示FileInputReader读取文件乱码的操作。
JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter
文章图片

1.2 使用BufferedReader读取中文乱码
package com.northcastle.reader_; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; /* * 文件编码格式为 GB2312; 输入流编码为 UTF8 * 二者的编码不一致,导致文件乱码。 */ public class ApplicationBufferedReaderLuanMa { public static void main(String[] args) throws IOException { String filePath = "D:\\EDailyRoutine\\java-io-test\\字符读取乱码演示.txt"; BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath)); String context = null; while ((context = bufferedReader.readLine()) != null){ System.out.println(context); } } }

JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter
文章图片

2.什么是字节-字符转换流
转换流 是将 字节流对象 装换成 字符流对象,主要是在转换的过程中可以指定编码格式
转换流的应用对象主要有两个 InputStreamReaderOutputStreamWriter
通过二者的命名可以认识到, 这两个转换流对象都是 字符流对象
InputStreamReader : 是Reader的子类,可以将 InputStream 转换成 Reader。
OutputStreamWriter : 是Writer的子类,可以将 OutputStream 转换成 Writer。
【二者在转换过程中,可以指定编码字符集,构造方法中直接传入参数即可】
可以看一下两个对象的继承关系图:
》1.InputStreamReader
JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter
文章图片

》2.OutputStreamWriter:
JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter
文章图片

3.InputStreamReader的使用
使用方式很简单,直接将 InputStream 的对象放入 InputStreamReader 的构造器中即可。
3.1 要读取的文件及编码格式
文件路径 : D:\\EDailyRoutine\\java-io-test\\字符读取乱码演示.txt
JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter
文章图片

3.2 案例代码
package com.northcastle.reader_; import java.io.*; /** * author : northcastle * createTime:2022/1/9 * 字节流转换成字符流,并指定文件编码格式,进行文件的读取 */ public class ApplicationInputStreamReader { public static void main(String[] args){ String filePath = "D:\\EDailyRoutine\\java-io-test\\字符读取乱码演示.txt"; //1.声明普通的 字节输入流对象 FileInputStream fileInputStream = null; //2.声明读取文件的编码格式 String charset = "GB2312"; //3.声明 转换流 对象 InputStreamReader inputStreamReader = null; //4.声明 处理流 对象 BufferedReader bufferedReader = null; //5.声明一个String对象来接收读取到的内容 String context = ""; try { //6.实例化 字节流 对象 fileInputStream = new FileInputStream(filePath); //7.实例化 转换流 对象,此处可以指定编码格式 inputStreamReader = new InputStreamReader(fileInputStream,charset); //8.实例化 处理流对象 bufferedReader = new BufferedReader(inputStreamReader); //9.执行读取操作,并把读取到的内容打印到控制台中 while ((context = bufferedReader.readLine()) != null){ System.out.println(context); }} catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //10.关闭最外层的处理流 if (bufferedReader != null){ try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

3.3 运行结果 JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter
文章图片

4.OutputStreamWriter的使用
OutputStreamWriter 可以将 字节输出流 包装成 字符输出流,同时可以指定编码格式。
4.1 案例代码
package com.northcastle.writer_; import java.io.*; /** * author : northcastle * createTime:2022/1/9 * 本例演示:使用转换流,指定编码方式写入数据到文件中 */ public class ApplicationOutputStramWriter { public static void main(String[] args) { //0.声明要写入的文件的路径 String filePath = "D:\\EDailyRoutine\\java-io-test\\字符写入-转换流演示.txt"; //1.声明 字节输出流对象 FileOutputStream fileOutputStream = null; //2.声明 转换流对象 OutputStreamWriter outputStreamWriter = null; //3.声明 处理流对象 BufferedWriter bufferedWriter = null; try { //4.实例化 字节输出流对象 fileOutputStream = new FileOutputStream(filePath); //5.实例化 转换流对象,同时指定编码格式为 utf8 outputStreamWriter = new OutputStreamWriter(fileOutputStream,"utf8"); //6.实例化 缓冲流对象 bufferedWriter = new BufferedWriter(outputStreamWriter); //7.往文件中写入内容 bufferedWriter.write("Hello OutputStreamWriter"); bufferedWriter.newLine(); bufferedWriter.write("这里是测试字节字符转换流的操作 OutputStreamWriter"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { //8.关闭最外层的 缓冲流即可 if (bufferedWriter != null){ try { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

4.2 运行结果
找到 目录中的文件,打开一看,文件内容正常! `右键另存为`可以查看文件编码格式也为 utf8!

JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter
文章图片

5.完成 Congratulations!
You are one step closer to success!

    推荐阅读