在 Java 中,BufferedOutputStream 类用于在缓冲区中捕获写入 BufferedOutputStream 的字节,并将整个缓冲区一次性写入底层 OutputStream 以提高性能。
缓冲可以大大加快 IO 的速度,尤其是将数据写入磁盘访问或网络时。
如果要为 OutputStream 类添加缓冲功能,只需将其封装在 BufferedOutputStream 中即可。
下面是一个将 OutputStream 包入 BufferedOutputStream 的示例:
OutputStream output = new BufferedOutputStream( new FileOutputStream("D:\\output-file.txt"));
是不是很简单。
你可以在创建 BufferedOutputStream 的构造方法中设置它内部使用的缓冲区大小。如下所示:
OutputStream output = new BufferedOutputStream( new FileOutputStream("c:\\output-file.txt"), 4096);
本例将内部缓冲区设置为 4 KB。
注意,最好使用 1024 字节倍数的缓冲区大小,这与硬盘等大多数内置缓冲区的效果最佳。
除了为输入流添加缓冲外,BufferedOutputStream 的行为与 OutputStream 完全相同。唯一的区别是,如果您需要绝对确保之前写入的数据已从缓冲区中写出并传输到网络或磁盘上,则可能需要调用 flush() 方法,刷新缓存。
要向 BufferedOutputStream 写入数据,可以使用 write() 方法。write() 方法接收一个 int,其中包含要写入的字节的字节值。因此,只有传入的 int 的低 8 位才会实际写入 BufferedOutputStream 目标地址。
下面是一个使用 write() 方法向 Java BufferedOutputStream 写入数据的示例:
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\output-text.txt")); bufferedOutputStream.write(123); // 写入数据
上面示例,将字节值 123 写入给定的 BufferedOutputStream。
由于 BufferedOutputStream 是 OutputStream 的子类,因此您也可以向 BufferedOutputStream 写入字节数组,而不是一次只写入一个字节。
下面是一个将字节数组写入 BufferedOutputStream 的示例:
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:\\output-text.txt")); byte bytes = new byte[]{1,2,3,4,5}; outputStream.write(bytes);
当您向 BufferedOutputStream 写入数据时,数据会缓存在内部的字节缓冲区中,直到字节缓冲区满为止,此时整个缓冲区会被写入底层的 OutputStream。
如果想确保所有写入的数据都已写入磁盘,而无需关闭 BufferedOutputStream,可以调用其 flush() 方法。调用 flush() 将确保迄今为止写入 BufferedOutputStream 的所有数据也全部写入底层 OutputStream,而且 flush() 也会在底层 OutputStream 上被调用。
下面是一个调用 BufferedOutputStream flush() 方法的示例:
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream("d:\\output-text.txt")); byte bytes = new byte[]{1,2,3,4,5}; outputStream.write(bytes); outputStream.flush(); // 看这里
一旦完成向 BufferedOutputStream 写入数据,就应该关闭它。您可以通过调用 BufferedOutputStream 的 close() 方法来关闭 BufferedOutputStream。关闭 BufferedOutputStream 也会关闭 BufferedOutputStream 正在写数据的底层 OutputStream。
下面是一个关闭 BufferedOutputStream 的示例:
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( new FileOutputStream("d:\\output-file.txt")); while(hasMoreData()) { int data = getMoreData(); bufferedOutputStream.write(data); } bufferedOutputStream.close();
这里省略了 hasMoreData() 和 getMoreData() 的具体实现,但它们对于理解本示例的原理其实并不十分重要。重要的是,一旦 while 循环结束,并完成向 BufferedOutputStream 写入数据,就会调用其 close() 方法关闭 BufferedOutputStream。
不过,上述示例并不健壮。如果 write() 方法抛出异常,close() 方法将永远不会被调用。异常将使程序退出上述代码所在的任何方法。
相反,您应该使用 try-with-resources 结构来关闭 BufferedOutputStream。下面是一个使用 try-with-resources 结构关闭 BufferedOutputStream 的示例:
try( BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:\\output-text.txt"))) { while(hasMoreData()) { int data = getMoreData(); output.write(data); } }
一旦退出 try 代码块,就会自动调用 BufferedOutputStream 的 close() 方法,因为 BufferedOutputStream 是在 try 代码块的括号内声明的。即使在 try 代码块内部出现异常,也会在异常向调用堆栈传播之前调用 close() 方法。