ITEEDU

Java Gossip: BufferedInputStream、 BufferedOutputStream

在介绍 FileInputStream、 FileOutputStream的 例子中,您使用了一个数组来作为数据读入的缓冲区,以档案存取为例的话,您知道磁盘存取的速度是远低于内存中的数据存取速度,为了减少对磁盘的存 ,您一次读入一定长度的数据,如上一个主题范例中的1024字节,而写入时也是一次写入一定长度的数据,这可以增加数据存取的效率。

BufferedInputStream与BufferedOutputStream可以为InputStream类的对象增加缓冲区功能,使用它们,您无需自行设计缓冲区。

BufferedInputStream的数据成员buf是个位数组,预设为2048字节大小,当读取数据来源时,例如档案, BufferedInputStream会尽量将buf填满,当使用read()方法时,实际上是先读取buf中的数据,而不是直接对数据来源作读取,当buf中的数据不足时,BufferedInputStream才会再从数据来源中提取数据。

BufferedOutputStream的数据成员buf是个位数组,预设为512个字节,当写入数据时,会先将资料存至buf中,当buf已满时才会一次将数据写至目的地,而不是每次写入都对目的地作写入。

将上一个主题的范例作个改写,这次不用自行设定缓冲区并进行判断了,使用BufferedInputStream、 BufferedOutputStream让程序看来简单一些,也比较有效率:

BufferedStreamDemo.java
package onlyfun.caterpillar;
import java.io.*;
public class BufferedStreamDemo {
	public static void main(String[] args) {
		try {
			byte[] data = new byte[1];
			File srcFile = new File(args[0]);
			File desFile = new File(args[1]);
			BufferedInputStream bufferedInputStream =
			new BufferedInputStream(
			new FileInputStream(srcFile));
			BufferedOutputStream bufferedOutputStream =
			new BufferedOutputStream(
			new FileOutputStream(desFile));
			System.out.println("复制档案:" +
			srcFile.length() + "字节");
			while(bufferedInputStream.read(data) != -1) {
				bufferedOutputStream.write(data);
			}
			// 将缓冲区中的数据全部写出
			bufferedOutputStream.flush();
			// 关闭串流
			bufferedInputStream.close();
			bufferedOutputStream.close();
		}
		catch(ArrayIndexOutOfBoundsException e) {
			System.out.println(
			"using: java UseFileStream src des");
			e.printStackTrace();
		}
		catch(IOException e) {
			e.printStackTrace();
		}
	}
}

为了确保缓冲区中的数据一定被写出,建议最后执行flush()将缓冲区中的数据全部写出目的串流中。

BufferedInputStream、BufferedOutputStream并没有改变来源InputStream或目的 OutputStream的行为,读入或写出时的动作还是InputStream、OutputStream负责, BufferedInputStream、BufferedOutputStream只是在这之前动态的为它们加上一些功能(像是缓冲区功能),在这边是 以档案存取串流为例,实际上您可以在其它串流对象上加上BufferedInputStream、BufferedOutputStream功能。