1 问题引出:不同编码读取乱码问题
1. 之前我们使用字符流读取中文是否有乱码?
● 没有的,因为代码编码和文件编码都是UTF-8。
2. 如果代码编码和文件编码不一致,使用字符流直接读取还能不乱码吗?
● 会乱码
● 文件编码和读取的编码必须一致才不会乱码。
步骤:使用相同编码读取不同编码的文件内容
需求:分别使用如下两种方式读取文件内容
①代码编码是UTF-8,文件编码也是UTF-8,使用字符流读取观察输出的中文字符结果。
②代码编码是UTF-8,文件编码使用GBK,使用字符流读取观察输出的中文字符结果
【案例】
public class InputStreamReaderDemo01 {
public static void main(String[] args) throws Exception {
// 代码UTF-8 文件 GBK "D:\\resources\\data.txt"
// 1、提取GBK文件的原始字节流。 abc 我
// ooo oo
InputStream is = new FileInputStream("D:\\resources\\data.txt");
// 2、把原始字节流转换成字符输入流
// Reader isr = new InputStreamReader(is); // 默认以UTF-8的方式转换成字符流。 还是会乱码的 跟直接使用FileReader是一样的
Reader isr = new InputStreamReader(is , "GBK"); // 以指定的GBK编码转换成字符输入流 完美的解决了乱码问题
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
}
2 字符输入转换流
1. 如果代码编码和文件编码不一致,使用字符流直接读取还能不乱码吗?
● 会乱码。
2. 如果如何解决呢?
● 使用字符输入转换流
● 可以提取文件(GBK)的原始字节流,原始字节不会存在问题。
● 然后把字节流以指定编码转换成字符输入流,这样字符输入流中的字符就不乱
字符输入转换流:InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流。
构造器 | 说明 |
public InputStreamReader(InputStream is) | 可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用,与默认的FileReader一样。 |
public InputStreamReader(InputStream is ,String charset) | 可以把原始的字节流按照指定编码转换成字符输入流,这样字符流中的字符就不乱码了(重点) |
【示例】
public class InputStreamReaderDemo01 {
public static void main(String[] args) throws Exception {
// 代码UTF-8 文件 GBK "D:\\resources\\data.txt"
// 1、提取GBK文件的原始字节流。 abc 我
// ooo oo
InputStream is = new FileInputStream("D:\\resources\\data.txt");
// 2、把原始字节流转换成字符输入流
// Reader isr = new InputStreamReader(is); // 默认以UTF-8的方式转换成字符流。 还是会乱码的 跟直接使用FileReader是一样的
Reader isr = new InputStreamReader(is , "GBK"); // 以指定的GBK编码转换成字符输入流 完美的解决了乱码问题
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
}
3 字符输出转换流
1. 如果需要控制写出去的字符使用的编码,怎么办?
● 可以把字符以指定编码获取字节后再使用字节输出流写出去:
● “我爱你中国”.getBytes(编码)
● 也可以使用字符输出转换流实现
字符输入转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流。
构造器 | 说明 |
public OutputStreamWriter(OutputStream os) | 可以把原始的字节输出流按照代码默认编码转换成字符输出流。几乎不用。 |
public OutputStreamWriter(OutputStream os,String charset) | 可以把原始的字节输出流按照指定编码转换成字符输出流(重点) |
【示例】
public class OutputStreamWriterDemo02 {
public static void main(String[] args) throws Exception {
// 1、定义一个字节输出流
OutputStream os = new FileOutputStream("io-app2/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("我爱中国1~~");
bw.write("我爱中国2~~");
bw.write("我爱中国3~~");
bw.close();
}
}
总结:
1. 字符输出转换流OutputStreamWriter的作用?
● public OutputStreamWriter(OutputStream os,String charset)
● 可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码