bufferedinputstream 不阻塞原理

bufferedinputstream是fileInputstream的子类,它继承自fileInputstream,所以它是在fileInputstream上的封装,自然而然效率肯定比fileInputstream好。

我们通过代码分析,来看为什么bufferedinputstream比fileInputstream效率高

        File file=new File("D:/text.txt");
        FileInputStream fileInputStream;
        byte b[]=new byte[10];
        int length;
        try {
            fileInputStream = new FileInputStream(file);
            while((length=fileInputStream.read(b))!=-1){
                String str= new String(b, 0, length);
                //do something 一系列业务处理
            }
        } catch (Exception e1) {
        }

上面代码是从fileInputStream中读取10个单位的字节放在b[]字节数组中,然后对这10个字节进行业务处理,注意这时候进行业务处理时fileInputStream.read(b)是阻塞的,即输入流处于阻塞状态,需等业务处理之后才再次执行while循环里的fileInputStream.read(b),这时候就再次fileInputStream读取10个字节,即又要去d盘text.txt中获取10个字节。当文件较大,读取的文件的次数增加,多次去硬盘执行io操作会大大影响性能。

        File file=new File("D:/text.txt");
        FileInputStream fileInputStream;
        byte b[]=new byte[10];
        int length;
        try {
            fileInputStream = new FileInputStream(file);
            BufferedInputStream buf=new BufferedInputStream(fileInputStream);
            while((length=buf.read(b))!=-1){
                String str= new String(b, 0, length);
                //do something 一系列业务处理
            }
        } catch (Exception e1) {
        }

用BufferedInputStream其实代码都是一样的,但是他们的read()方法内部执行的原理很不一样。
当BufferedInputStream buf=new BufferedInputStream(fileInputStream)初始化时,它定义一个长度为8192的字节数组
BufferedInputStream 构造方法源码

 private static int defaultBufferSize = 8192;

 /**
     * Creates a <code>BufferedInputStream</code>
     * and saves its  argument, the input stream
     * <code>in</code>, for later use. An internal
     * buffer array is created and  stored in <code>buf</code>.
     *
     * @param   in   the underlying input stream.
     */
    public BufferedInputStream(InputStream in) {
        this(in, defaultBufferSize);
    }
    public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

执行BufferedInputStream.read(b)时,他首先从BufferedInputStream的缓冲区读取字节,如果缓冲区没有字节,它会每次从输入流中获取8192位字节加载到它的缓冲区中,并且它每次从输入流中获取字节不会阻塞,会一直执行指导字节获取完毕;然后再从缓冲区读,从内存中获取字节比从硬盘快的多。这样执行BufferedInputStream.read(b)时,它不用等一系列业务处理玩再去硬盘文件读取10个字节,这样就不会发生阻塞。大大节省时间。
并且fileInputStream.read(b)是每次从文件中读取10个字节,这样执行io操作次数很多,效率低,内存占用高,而BufferedInputStream每次是读取8192字节,执行io次数少的多,系统占用内存低很多。

其实,我们都可以自己写段代码实现BufferedInputStream的功能。

        File file=new File("D:/text.txt");
        FileInputStream fileInputStream;
        byte b[]=new byte[8192];
        byte buffer[];
        int length;
        try {
            fileInputStream = new FileInputStream(file);
            buffer=new byte[fileInputStream.available()];
            while((length=buf.read(b))!=-1){
                int bufferLength=buffer.length;
                for(int i=0;i<length;i++){
                    buffer[bufferLength]=b[i];
                }
            }
            int bufferSize=buffer.length;
            while(bufferSize>0){
               String str;
               if(bufferSize<10){
                    str=new String(b,0,bufferSize);
                }else{
                    str= new String(b, 0, 10);
                }
               //do something 一系列业务处理

               bufferSize=bufferSize-10
            }
        } catch (Exception e1) {
        }

猜你喜欢

转载自blog.csdn.net/CSDNzhangtao5/article/details/53786426