1.由乱码引出的问题
1.字符流
在处理文本文件时比较方便,且对文本文件的读写效率要高;
2.在读取文件的时候,如果文件的格式和读入流的格式不一致,则会导致读入的内容乱码
。
下面,我们通过一个例子来观察一下这个问题:1.1 另存为文件的格式为 GBK
(以下操作在windows上进行)
【JAVA|JAVA IO - 一文搞懂字节-字符转换流 - InputStreamReader+OutputStreamWriter】文件 :D:\EDailyRoutine\java-io-test\\字符读取乱码演示.txt
另存为
一下,选择编码格式为GB2312
.
文件内容中包含中文,内容如下:
hello FileInputReader
你好,这里演示FileInputReader读取文件乱码的操作。
文章图片
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);
}
}
}
文章图片
2.什么是字节-字符转换流
转换流
是将字节流对象
装换成字符流对象
,主要是在转换的过程中可以指定编码格式
。
转换流
的应用对象主要有两个InputStreamReader
和OutputStreamWriter
。
通过二者的命名可以认识到, 这两个转换流对象都是字符流对象
。
InputStreamReader : 是Reader的子类,可以将 InputStream 转换成 Reader。
OutputStreamWriter : 是Writer的子类,可以将 OutputStream 转换成 Writer。
【二者在转换过程中,可以指定编码字符集,构造方法中直接传入参数即可】
可以看一下两个对象的继承关系图:》1.InputStreamReader
文章图片
》2.OutputStreamWriter:
文章图片
3.InputStreamReader的使用
使用方式很简单,直接将 InputStream 的对象放入 InputStreamReader 的构造器中即可。3.1 要读取的文件及编码格式
文件路径 :D:\\EDailyRoutine\\java-io-test\\字符读取乱码演示.txt
文章图片
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 运行结果
文章图片
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!
文章图片
5.完成 Congratulations!
You are one step closer to success!
推荐阅读
- 项目|云相册
- Java|Java多线程,JUC学习
- kafka|Kafka详细教程-及热点面试题
- 面试|裸辞后的两个月,我拿到了360的offer
- springSecurity|3.spring security授权流程
- Java|从无到有构建亿级高性能高并发高可用的亿级微服务秒杀系统
- java|JVM 和 HotSpot 的区别()
- 教育|超超超级详细的java入门必备基础知识
- 毕设项目|Java毕业设计-在线点餐系统