java的io缓冲区buffered,他们高效在哪里,底层还是一个一个字节读到底哪里高效了

这就涉及到一些概念了——
读、写这两个操作的能力并不是完全对等的。这个你可以去查看硬盘的读写能力值,你会发现读取的能力要高于写入的能力。
【java的io缓冲区buffered,他们高效在哪里,底层还是一个一个字节读到底哪里高效了】 对硬盘O(取义output)进行读取,再将读取到的数据瞬间写入到硬盘I(取义input),O输出数据读取数据的能力远大于I接受数据的能力。这是实际O输出的能力可以认为等同于I的输入能力。换句话说O在输出数据的时候会顾忌到I的输入能力,只能选择限制自己的能力。
如果这时在O和I之间设置一块内存(内存IO能力远强于实际硬盘的IO能力),那么这时候硬盘O可以对内存全力输出,硬盘I也可以全力输入。
缓冲,充当的就是这个蓄水池的作用,你这里的bufferedInputStream套在外面也充当了这个蓄水池的作用。
无限制运送物品,每遇见一个物品就运送一次;相较于收集到一定数量再进行运送;各自有各自的优缺点,不同的场景有不同的需求,不能一概而论,也不可一概而论。

■网友
带缓冲区的底层并不是一个字节一个字节读取的,BufferedInputStream的fill()方法中你可以看到真实数据填充操作是getInIfOpen().read(buffer, pos, buffer.length - pos), BufferedInputStream包装FileInputStream,这里调用的就是FileInputStream的read(byte b, int off, int len)方法,继而调用本地方法readBytes(byte b, int off, int len),这个方法底层是可以一次性拷贝多个字节的。那为什么直接使用FileInputStream的读多字节方法呢? 我的理解是如果你要直接使用FileInputStream的读多字节功能,那么你其实就是需要写出BufferedInputStream的缓冲功能,因为在定义接收的这个buffer数组的时候,你必须像BufferedInputStream那样不断得对缓冲数组进行操作。
现在就可以来说说为什么BufferedInputStream能提高效率了。
输入流对象包含了缓冲区,可以一次性读取多个字节到缓冲区中,这个在读层面不用一个字节一个字节地进行内存拷贝操作,就提高了读的效率;读操作通常伴随着写操作,输出流对象包含了缓冲区,同样地不用每次都一个字节一个字节的写,可以读缓冲区,一次性操作多个字节,这样提高了写的效率。

■网友
要想读懂BufferedInputStream的源码,就要先理解它的思想。BufferedInputStream的作用是为其它输入流提供缓冲功能。创建BufferedInputStream时,我们会通过它的构造函数指定某个输入流为参数。BufferedInputStream会将该输入流数据分批读取,每次读取一部分到缓冲中;操作完缓冲中的这部分数据之后,再从输入流中读取下一部分的数据。 为什么需要缓冲呢?原因很简单,效率问题!缓冲中的数据实际上是保存在内存中,而原始数据可能是保存在硬盘或NandFlash等存储介质中;而我们知道,从内存中读取数据的速度比从硬盘读取数据的速度至少快10倍以上。 那干嘛不干脆一次性将全部数据都读取到缓冲中呢?第一,读取全部的数据所需要的时间可能会很长。第二,内存价格很贵,容量不像硬盘那么大。


    推荐阅读