设置了缓冲区的输出流之后,应用程序就可以将各个字节写入底层输出流系统中,而不必针对每次字节写入调用底层系统。

什么意思?如果我们是用之前的方式,例如文件输出流的方式,那么当每次写一个字节,就需要跟硬盘完成一次交互,也就是写到硬盘上,这样的话每个字节都需要写。而字节从程序到操作系统再写到硬盘上是需要花费时间的,而有了缓冲区就不一样了,有了缓冲区的话,每调用一次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 }

 

版权声明:本文为EvanTheGreat原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/EvanTheGreat/p/14426408.html