读书人

Java I/O关于缓冲区一部分提高性能的源

发布时间: 2012-12-18 12:43:41 作者: rapoo

Java I/O关于缓冲区部分提高性能的源码分析【Stream】
拿FileInputStream来举例:
class FileInputStream extends InputStream


从顶级的InputStream开始

InputStream 定义了3个read方法。

read();read(byte[]);read(byte[],int off,int len);

第二个read(byte[])其实就是read(b, 0, b.length) ,所以等同于第三个;

第一个read()方法,api介绍如下:
public native int read() throws IOException; private native int readBytes(byte b[], int off, int len) throws IOException; public int read(byte b[]) throws IOException {return readBytes(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException {return readBytes(b, off, len); }
这里两个read()方法都是用本地方法实现,因为FileInputStream是跟底层的操作系统交互的,没有比用本地方法来实现的性能更好,更容易的了。所以这里就采用了第三段里的建议,真正实现了缓存的功能,虽然我们并不知道如何实现的。

那么既然FileInputStream已经实现了缓存来提高性能,那么BufferedInputStream又拿来干嘛?
先看api介绍:
FileInputStream fis=new FileInputStream("d:\\a.txt");BufferedInputStream bis=new BufferedInputStream(fis);int data=0;while((data=bis.read())!=-1){//......}
这样虽然也是一次读一个字节,但不是每次都从底层读取数据,而是一次调用底层系统读取了最多buf.length个字节到buf数组中,然后从buf中一次读一个字节,减少了频繁调用底层接口的开销。
等同于
FileInputStream fis=new FileInputStream("d:\\a.txt");byte[] mybuff=new byte[1024];int count=0;while((count=fis.read(mybuff))!=-1){     //......}


如果是用BufferedInputStream的read(byte[],int off,int len)那缓冲区则由传入的byte[]来充当(虽然内部其实有时候还用到了buf,但表现出来的就是用传入的byte[]来缓冲)。

讲了这么多,那如果要缓冲那该用FileInputStream还是BufferedInputStream呢?回到上面紫色的文字,BufferedInputStream主要不是提供buf,而是封装了缓冲和标记/回读的功能。如果你既不用到标记/回读功能,又不要操作中间的缓冲数组,那显而易见直接用FileInputStream的read(byte[],int off,int len)是效率最高的。

最后说下为什么用缓冲性能就更好,因为应用程序可以将多个字节写入底层输出流中(native read(byte)),而不必针对每个字节写入都调用底层系统(native read())。OutputStream原理基本差不多,这里就不说了。

读书人网 >编程

热点推荐