缓冲区输出流
设置了缓冲区的输出流之后,应用程序就可以将各个字节写入底层输出流系统中,而不必针对每次字节写入调用底层系统。
什么意思?如果我们是用之前的方式,例如文件输出流的方式,那么当每次写一个字节,就需要跟硬盘完成一次交互,也就是写到硬盘上,这样的话每个字节都需要写。而字节从程序到操作系统再写到硬盘上是需要花费时间的,而有了缓冲区就不一样了,有了缓冲区的话,每调用一次write方法,这个字节不会真的写到硬盘上,而是先在缓冲区待着,当这个缓冲区的字节到达一定数量的时候,系统就会把缓冲区中所有的字节写到硬盘上。相当于缓冲区有一个数组,每调用一次write方法,系统是先放到这个临时数组里面,等数组存不下了,再一次性写到硬盘里面,这样就会节约性能。
下面来看下代码:
1 package com.hw.file0221;
2
3 import java.io.BufferedOutputStream;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 public class Demo1BufferedOutputStream {
9 public static void TestBufferedOutputStream(){
10 BufferedOutputStream output = null;
11
12 try {
13 output = new BufferedOutputStream(new FileOutputStream("F://test01.txt"));
14 //这样就完成了对缓冲区输出流的构造
15 } catch (FileNotFoundException e) {
16 // TODO Auto-generated catch block
17 e.printStackTrace();
18 }finally{
19 try {
20 if(output != null){
21 output.close();
22 }
23 } catch (IOException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }
27 }
28 }
29 }
这里需要注意的一点就是,new BufferedOutputStream后面不能直接跟文件名,必须要再写一个new FileOutputStream,即给定另外一个输出流才可以,这里就直接采用FileOutputStream把他构造出来。为什么必须给定一个OutputStream的对象呢?这是因为,没有为什么,就是这么用的。因此,我们也把缓冲区输出流叫做包装流。上面代码中,相当于FileOutputStream的对象被BufferedOutputStream所管理了。其实也就是在原有流的基础上加了个缓冲区,这个缓冲区相当于一个数组。
缓冲区输出流里面的一些基本方法还是与FileOutputStream是一样的,同样可以在文件不存在的情况下给你创建一个文件,然后在文件名后面加个true的话也就变成了追加模式。对于write方法,如果采取普通的FileOutputStream方法,他是来一个字节就弄到硬盘上,就跟硬盘交互一次,这样很浪费性能。而对于缓冲区输出流,它不会马上写到硬盘上,而是先存到数组里,又因为这个数组有内置的大小,等到存不下了,再写入到硬盘上。调用关闭方法的时候也会把数组里面已经有了的全部弄到硬盘上,不管满没满。如果不调用close方法这个缓冲区数组又没满的话,是不会写到硬盘上的。
或者,如果忘记关闭,缓冲区数组又没满的话,可以调用一个flush方法,即(以上面的代码为基准)output.flush();刷新缓冲区,这样也可以把缓冲区数组里的数据写到硬盘上,当然这么做,流不会关闭,他只是刷新了缓冲区而已,刷新完缓冲区之后还是可以继续写数据的。
这里我们通过程序来演示一下:
1 package com.hw.file0221;
2
3 import java.io.BufferedOutputStream;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 public class Demo1BufferedOutputStream {
9 public static void main(String[] args) {
10 BufferedOutputStream output = null;
11
12 try {
13 output = new BufferedOutputStream(new FileOutputStream("F://骚操作//demotest01.txt"));
14 //这样就完成了对缓冲区输出流的构造
15
16 output.write(\'a\');
17 output.write(\'p\');
18 output.write(\'i\');
19 output.flush();
20 output.write(\' \');
21 output.write(\'i\');
22 output.write(\'s\');
23
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }finally{
28 // try {
29 // if(output != null){
30 // output.close();
31 // }
32 // } catch (IOException e) {
33 // // TODO Auto-generated catch block
34 // e.printStackTrace();
35 // }
36 }
37 }
38
39 }
可见在上面的代码中,我把关闭方法注释掉了,这样一来,在flush之后的数据就没有写入了。
对于缓冲区的大小,这里我们也来演示一下:
1 package com.hw.file0221;
2
3 import java.io.BufferedOutputStream;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 public class Demo1BufferedOutputStream {
9 public static void main(String[] args) {
10 BufferedOutputStream output = null;
11 try {
12 FileOutputStream fileoutput = new FileOutputStream("F://骚操作//demotest01.txt");
13 //这里可以指定缓冲区大小为5
14 output = new BufferedOutputStream(fileoutput,5);
15
16 output.write(\'a\');
17 output.write(\'b\');
18 output.write(\'c\');
19 output.write(\'d\');
20 output.write(\'e\'); //到这里会自动刷新,把这些数据全部写到硬盘里
21 output.write(\'f\'); //从这里开始,因为不够5个,所以只是停留在缓冲区数组里
22 output.write(\'g\');
23
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }
28
29 }
30 }
一般来说,除了在finally里面加了关闭之外,还会在写入数据的操作结束之后,加一个flush方法,这样就多了一重保障,不至于出现异常使数据全部丢失。
write方法也可以传递一个字符串,调用getBytes()方法把字符串转换成字节数组。
1 package com.hw.file0221;
2
3 import java.io.BufferedOutputStream;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7
8 public class Demo1BufferedOutputStream {
9 public static void main(String[] args) {
10 BufferedOutputStream output = null;
11 try {
12 FileOutputStream fileoutput = new FileOutputStream("F://骚操作//demotest01.txt");
13 //这里可以指定缓冲区大小为5
14 output = new BufferedOutputStream(fileoutput);
15
16 output.write(\'a\');
17 output.write(\'b\');
18 output.write(\'c\');
19
20 output.flush();
21
22 output.write("abcdefg".getBytes());
23
24 } catch (IOException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }finally{
28 try {
29 if(output != null){
30 output.close();
31 }
32 } catch (IOException e) {
33 // TODO Auto-generated catch block
34 e.printStackTrace();
35 }
36 }
37
38 }
39 }