1,OutputStreamWriter
/* 通过以前的输入输出流读写数据时,不能指定编码,使用的是默认的gbk,这时候就要用到转换流了
* 转换流
* java.io.OutputStreamWriter 继承Writer类
* 就是一个字符输出流,写文本文件
* write()字符,字符数组,字符串
*
* 字符通向字节的桥梁,将字符流转字节流
*
* OutputStreamWriter 使用方式
* 构造方法:
* OutputStreamWriter(OuputStream out)接收所有的字节输出流
* 但是: 字节输出流: FileOutputStream
*
* OutputStreamWriter(OutputStream out, String charsetName)
* String charsetName 传递编码表名字 GBK UTF-8
*
* OutputStreamWriter 有个子类, FileWriter
*注意转换流只是将字符转换为字节,写入还是通过FileOutputStream
*/
具体用法
/*
* 转换流对象OutputStreamWriter写文本
* 采用UTF-8编码表写入
*/
//创建字节输出流,绑定文件
FileOutputStream fos = new FileOutputStream("e:utf.txt");
//创建转换流对象,构造方法保证字节输出流,并指定编码表是UTF-8
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
osw.write("你好");//字符,字符数组,字符串
osw.close();//fos包装在osw内,无需关闭
原理示意
java程序转换流 查码表字节流 字节(文件)
你好 -> OutputStream -> utf-8-> FileOutputStream -> -45-34-23
2,InputStreamReader
和OutputStream大同小异,直接上代码
/*
* 转换流,InputSteamReader读取文本
* 采用UTF-8编码表,读取文件utf
*/
//创建自己输入流,传递文本文件
FileInputStream fis = new FileInputStream("c:\\utf.txt");
//创建转换流对象,构造方法中,包装字节输入流,同时写编码表名
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
byte[] b = new byte[1024];
int len = 0;
while((len = isr.read(b))!=-1){
System.out.print(new String(b,0,len));
}
isr.close();
附上原理图
3,转换流和子类区别
发现有如下继承关系:
OutputStreamWriter:
|--FileWriter:
InputStreamReader:
|--FileReader;
父类和子类的功能有什么区别呢?
OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。
FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。
FileReader fr = new FileReader("a.txt");
这三句代码的功能是一样的,其中第三句最为便捷。
注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。什么时候用子类呢?
条件:
1、操作的是文件。2、使用默认编码。
总结:
字节--->字符 : 看不懂的--->看的懂的。 需要读。输入流。 InputStreamReader
字符--->字节 : 看的懂的--->看不懂的。 需要写。输出流。 OutputStreamWriter