专注Java教育14年 全国咨询/投诉热线:444-1124-454
星辉LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 深入解析IO转换流

深入解析IO转换流

更新时间:2020-11-19 17:30:06 来源:星辉 浏览947次

我们在学习字符流(FileReader、FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputStreamWriter,这又是什么意思呢?这其中就涉及到了IO转换流的相关知识。


为了方便我们的理解可以先来看一下转换流原理图:

image.png


一、OutputStreamWriter类

查阅OutputStreamWriter的API介绍,OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节。它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。

public static void writeCN() throws Exception {

//创建与文件关联的字节输出流对象

FileOutputStream fos = new FileOutputStream("c:\\cn8.txt");

//创建可以把字符转成字节的转换流对象,并指定编码

OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");

//调用转换流,把文字写出去,其实是写到转换流的缓冲区中

osw.write("你好");//写入缓冲区。

osw.close();

}

OutputStreamWriter流对象,它到底如何把字符转成字节输出的呢?

其实在OutputStreamWriter流中维护自己的缓冲区,当我们调用OutputStreamWriter对象的write方法时,会拿着字符到指定的码表中进行查询,把查到的字符编码值转成字节数存放到OutputStreamWriter缓冲区中。然后再调用刷新功能,或者关闭流,或者缓冲区存满后会把缓冲区中的字节数据使用字节流写到指定的文件中。

java.io.OutputStreamWriter extends Writer

OutputStreamWriter: 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂)

继续自父类的共性成员方法:

- void write(int c) 写入单个字符。

- void write(char[] cbuf)写入字符数组。

- abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。

- void write(String str)写入字符串。

- void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。

- void flush()刷新该流的缓冲。

- void close() 关闭此流,但要先刷新它。

构造方法:

OutputStreamWriter(OutputStream out)创建使用默认字符编码的OutputStreamWriter。

OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。

参数:

OutputStream out:字节输出流,可以用来写转换之后的字节到文件中

String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8

使用步骤:

1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称

2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)

3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)

4.释放资源


二、InputStreamReader类

查阅InputStreamReader的API介绍,InputStreamReader 是字节流通向字符流的桥梁:它使用指定的字符编码表读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

java.io.InputStreamReader extends Reader

InputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。(解码:把看不懂的变成能看懂的)

继承自父类的共性成员方法:

int read() 读取单个字符并返回。

int read(char[] cbuf)一次读取多个字符,将字符读入数组。

void close() 关闭该流并释放与之关联的所有资源。

构造方法:

InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。

InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。

参数:

InputStream in:字节输入流,用来读取文件中保存的字节

String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8

使用步骤:

1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称

2.使用InputStreamReader对象中的方法read读取文件

3.释放资源

注意事项:

构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码

代码演示

public class InputStreamReaderDemo {

public static void main(String[] args) throws IOException {

//演示字节转字符流的转换流

readCN();

}

public static void readCN() throws IOException{

//创建读取文件的字节流对象

InputStream in = new FileInputStream("c:\\cn8.txt");

//创建转换流对象

//InputStreamReader isr = new InputStreamReader(in);

//这样创建对象,会用本地默认码表读取,将会发生错误解码的错误

InputStreamReader isr = new InputStreamReader(in,"utf-8");

//使用转换流去读字节流中的字节

int ch = 0;

while((ch = isr.read())!=-1){

System.out.println((char)ch);

}

//关闭流

isr.close();

}

}

在读取指定的编码的文件时,一定要指定编码格式,否则就会发生解码错误,而发生乱码现象。


通俗一点来说,磁盘中的存储的数据都是“看不懂”的,也就是以字节形式存储的。而内存中存储的数据都是“看得懂”的,也就是以字符形式存储的。把“看得懂”的数据转换成"看不懂"的数据,即把字符流编码成字节流。好了,IO转换流的知识就讲到这里,感兴趣的小伙伴可以在消化完本文之后,观看本站的Java教程,继续深入学习Java IO流的知识。


提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>