转换流
一、问题引入
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 的作用是啥?
- 可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码