1.BufferedOutputStream
在介绍FileInputStream和FileOutputStream的例子中,使用了一个byte数组来作为数据读入的缓冲区,以文件存取为例,硬盘存取的速度远低于内存中的数据存取速度。为了减少对硬盘的存取,通常从文件中一次读入一定长度的数据,而写入时也是一次写入一定长度的数据,这可以增加文件存取的效率。
java.io.BufferedInputStream与java.io.BufferedOutputStream可以为InputStream、OutputStream类的对象增加缓冲区功能。构建BufferedInputStream实例时,需要给定一个InputStream类型的实例,实现BufferedInputStream时,实际上最后是实现InputStream实例。同样地,在构建BufferedOutputStream时,也需要给定一个OutputStream实例,实现BufferedOutputStream时,实际上最后是实现OutputStream实例。
BufferedInputStream的数据成员buf是一个位数组,默认为2048字节。当读取数据来源时,例如文件,BufferedInputStream会尽量将buf填满。当使用read()方法时,实际上是先读取buf中的数据,而不是直接对数据来源作读取。当buf中的数据不足时,BufferedInputStream才会再实现给定的InputStream对象的read()方法,从指定的装置中提取数据。
import java.io.*;
class TestBufferedOutputStream {
public static void main(String[] args) {
try {
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("e:/a.java"));
for (int i = 0; i < 200; i++) {
out.write(i);
}
out.flush();
} catch (Exception e) {
}
}
}
数据刷新到硬盘有两个触发条件,超过BufferedOutputStream 的缓冲区大小或者显示调用了flush。
public synchronized void write(int b) throws IOException {
if (count >= buf.length) {
flushBuffer();
}
buf[count++] = (byte)b;
}
注意,直接调用调用FileOutputStream的flush是没有效果的,因为它木有实现这个方法,因此使用的是OutputStream的flush,它的flush什么也不干。
2.几个io操作的底层调用
1.网络bio,读写
socketInputStream,socketOutputStream
最终会调用
private native int socketRead0(FileDescriptor fd, byte b[], int off, int len,int timeout)
private native void socketWrite0(FileDescriptor fd, byte[] b, int off, int len) throws IOException;
2.文件bio
FileInputStrem,FileOutputStream
private native int readBytes(byte b[], int off, int len) throws IOException;
private native void writeBytes(byte b[], int off, int len) throws IOException;
以上都是一次linux系统调用。