如果代码编码和被读取的文本文件的编码是一致的,使用字符流读取文本文件时不会出现乱码。
如果代码编码和被读取的文本文件的编码是不一致的,使用字符流读取文本文件时会出现乱码。
package cn.chang.d3_transform_stream; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.Reader; /** * 目标: 掌握不同编码读取乱码的问题 */ public class Test1 { public static void main(String[] args) { try ( // 1. 创建一个文件字符输入流与源文件接通 // 分析:代码编码是UTF-8; // 文件编码也是UTF-8,那就不会有乱码。 //Reader fr = new FileReader("io-app2/src/chang04.txt"); // 再新建chang06.txt,将编码改成GBK。然后再运行,就出现乱码。 Reader fr = new FileReader("io-app2/src/chang06.txt"); // 2. 把文件字符输入流包装成缓冲字符输入流 BufferedReader br = new BufferedReader(fr); ) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } }运行结果:
代码分析:
文件时一个GBK的编码,1占一个字节,在GBK中汉字占一个两个字节。代码编码是UTF-8,1占一个字节,英文占一个字节,UTF-8,一个汉字占3个字节,最终肯定会出现乱码的。
文件的编码就是GBK,那字符输入转换流就可以解决字符乱码的问题。
InputStreamReader(字符输入转换流)
解决不同编码时,字符流读取文本内容乱码的问题。
解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转换成字符输入流,这样字符输入流中的字符就不乱码了。
代码:
package cn.chang.d3_transform_stream; import java.io.*; import java.nio.charset.StandardCharsets; /** * 目标:掌握字符输入转换流的作用 */ public class InputStreamReaderTest2 { public static void main(String[] args) { try( // 1. 得到文件的原始字节流(GBK的字节流形式) InputStream is = new FileInputStream("io-app2/src/chang06.txt"); // 2. 把原始的字节输入流按照指定的字符集编码转换成字符输入流 InputStreamReader isr = new InputStreamReader(is, "GBK"); // 3. 把字符输入流包装成缓冲字符输入流 BufferedReader br = new BufferedReader(isr); ) { String line; while( (line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } }运行结果:
字符输出转换流:
需要控制写出去的字符使用什么字符集编码,该咋整?
1、调用String提供的getBytes方法解决?
2、可以使用字符输出转换流来实现。
OutputStreamWriter字符输出转换流:
作用:可以控制写出去的字符使用什么字符集编码。
解决思路:获取字节输出流,再按照指定的字符集编码将其转换成字符输出流,以后写出去的字符就会用该字符集编码了。
代码:
package cn.chang.d3_transform_stream; import java.io.*; /** * 目标:掌握字符输出转换流的使用 */ public class OutputStreamWriterTest3 { public static void main(String[] args) { // 指定写出去的字符编码 try( // 1. 创建一个文件字节输出流 OutputStream os = new FileOutputStream("io-app2/src/chang07out.txt"); // 2. 把原始的字节输出流,按照指定的字符集编码转换成字符输出转换流。 Writer writer = new OutputStreamWriter(os, "GBK"); // 3. 把字符输出流包装成缓冲字符输出流 BufferedWriter bw = new BufferedWriter(writer); ) { bw.write("我是中国人"); bw.newLine(); bw.write("我爱中国"); bw.newLine(); } catch (Exception e) { e.printStackTrace(); } } }运行结果: