刚开始学习流的时候,感觉一会儿输出流,一会儿输入流的,一会儿System.out,一会儿又转换流的。很晕。
最后毕老师给了一个总结,归纳出了IO操作的规律。感觉总结的非常好,虽然刚看第一遍的时候还是很晕,不过现在终于融汇贯通。
下面我就用自己的理解,总结一下IO流操作的一般规律:
在使用IO操作流之前,我们要问自己一下四个问题:
A. 源和目的都有吗?(初步确定体系)
B. 源和目的操作的是字符吗?(确定体系)
C. 源和目的的设备都是些什么?(辅助确定具体对象)
D. 需要提高输入和输出的效率吗?
补充:源的设备:内存,硬盘,键盘
目的的设备:内存,硬盘,控制台
当明确了以上几点之后我们就可以确定到底应该使用那一个流对象。
Demo1:拷贝一个文本文件的副本。
分析:
A.源和目的都有。
所以,源可以选择:Reader或者InputStream
目的可以选择:Writer 或者 OutputStream
B.操作的都是字符数据。
所以,源应该选择:Reader
目的应该选择:Writer
C.源的设备是:硬盘。目的的设备是:硬盘。
所以:源应该使用:FileReader
目的应该使用:FileWriter
D. 需要提高输入和输出效率。
所以可以使用相应的装饰类。
源使用:BufferedReader
目的使用:BufferedWriter
具体代码如下:
BufferedReader bufr = new BufferedReader(new FileReader("1.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("copy_1.txt"));
Demo2:将从键盘输入的数据存储到文件中。
分析:
A. 源和目的都有。
所以,源可以选择:Reader或者InputStream
目的可以选择:Writer 或者 OutputStream
B. 操作的都是字符数据。
所以,源应该选择:Reader
目的应该选择:Writer
C. 源的设备是:键盘。目的的设备是:硬盘。
因为源是键盘所以应该使用System.in,但是键盘是字节流,但是我们使用的体系应该是Reader(字符)体系的。所以要使用InputSreamReader(转换流)将字节流转换为字符流在进行操作。
目的应该使用:FileWriter
D. 需要提高输入和输出效率。
所以可以使用相应的装饰类。
源使用:BufferedReader
目的使用:BufferedWriter
具体代码如下:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new FileWriter("copy_1.txt"));
转换流详解:
查阅api我们知道转换流是定义在字符体系中的,那么我们什么时候应该使用转换流呢?
InputStreamReader:是字节数据通向字符数据的桥梁。
当我们要将字节数据转换成字符数据时使用,在转换成字符数据时,我们必须指定字符编码方式,如GB2312、UTF-8等
如果我们转化的时候使用的编码是系统默认编码,那么我们可以使用FileReader。其实,FileReader就是对编码方式为系统默认的转换流(public InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。)的一个封装,这样使用起来比较简单。
OutputStreamWriter:是字符数据通向字节数据的桥梁。
当创建使用指定字符集的 OutputStreamWriter 时使用。
简单说就是,我们如果要输出一些文本到控制台上,那么我们知道控制台的标准输出流是System.out,是字节流,我们在操作时,就要将字符数据转化成字节数据,这样控制台才能正确显示,所以就用到了OutputStreamWriter。但是这个地方要注意,如果我们拿到一个文本他的编码方式是UTF-8,但是你的电脑是简体中文的。如果你在使用OutputStreamWriter的时候没有指明转换时使用的码表,那么系统就会按照系统默认的码表转换(一般是GBK)。这样肯定会出问题了,所以,记住了!当我们要指定编码方式的时候就使用转换流InputStreamReader和OutputStreamWriter。
Demo3:将从键盘输入字符的数据显示在屏幕上。
快速分析:
A. 使用键盘,输入流就是System.in,但是输入的是字符,所以用到转换流:InputStreamReader(System.in)
B. 输出到屏幕上,顾名思义就是控制台。所以输出流是System.out,因为是文本输出,所以使用OutputStreamWriter(System.out)
C. 如果要提高输入输出效率,就得使用装饰类。
所以最终代码如下:
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(System.out));
如果要求改为将键盘输入的数据存入一个文件中,并按照UTF-8的编码形式。
BufferedReader bufr =
new BufferedReader ( new InputStreamReader(System.in) );
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter
( new FileOutputStream("TransDemo.txt") , "UTF-8" ) );