Java BufferedInputStream如何从操作系统请求数据块

Java BufferedInputStream如何从操作系统请求数据块,java,io,stream,Java,Io,Stream,我读到了这个问题:根据作者的说法,BufferedInputStream(BIS)比FileInputStream(FIS)快,因为当在FileInputStream中调用方法read()时,它总是使用本机API进行系统调用以获取单个字节,虽然BufferedInputStream的作用与此相同,但它需要来自操作系统的字节块,并将它们存储在名为buf的本地字段中,该字段在BIS类中声明,然后当read()被称为BIS时,从buf数组返回字节 我查看了BIS的代码,特别是read()方法,但我不清

我读到了这个问题:根据作者的说法,BufferedInputStream(BIS)比
FileInputStream(FIS)
快,因为当在
FileInputStream中调用方法
read()
时,它总是使用本机API进行系统调用以获取单个字节,虽然
BufferedInputStream
的作用与此相同,但它需要来自操作系统的字节块,并将它们存储在名为
buf
的本地字段中,该字段在BIS类中声明,然后当
read()
被称为BIS时,从
buf
数组返回字节

我查看了BIS的代码,特别是
read()
方法,但我不清楚何时会发生这种情况,何时BIS需要字节块而不是一个字节。方法
read()
首先检查
if(pos>=count)
如果是,则调用
fill()
方法,该方法首先检查buf是否已满,如果buf有空间,则输入流的方法称为
公共int read(字节b[],int off,int len)
其中b[]是我们的缓冲区,在这个方法的内部,我们可以看到它在循环内部进行系统调用,这个循环等于
len
param

for (; i < len ; i++) {
                c = read();
(;i{ c=读取();

我是否遗漏了某些内容,或者BIS和FIS两个类都将执行相同数量的系统调用,以便分别获取每个字节?

您找错了地方


InputStream提供了
int read(字节[]b,int off,int len)
的实现,它确实调用了
read()
在循环中。因此,如果BuffredInputStream包装的具体InputStream没有覆盖此方法,则不会有性能改进。但是,您链接的问题专门讨论FileInputStream,它通过调用
本机int readBytes(字节b[],int off,int len)覆盖此方法

您链接的答案继续;使用BufferedInputStream,该方法将委托给重载的read()方法,该方法读取8192个字节,并将它们缓冲到需要为止。它仍然只返回单个字节(但保留其他字节)。值得注意的是,在大多数情况下,您的应用程序都是IO绑定的。因为IO速度很慢。读取8196(8k)个块的ByteBuffer会更快。具有64k ByteBuffer的FileChannel会更快(通常)。一般来说,如果需要速度和性能,请使用更大的缓冲区进行读取。@markspace我知道读取速度更快,但我想了解为什么,我想知道BIS如何获取优化读取字节块而不是单个字节,尽管我发现它在循环中执行了很多旧的read()调用。答案是“它很复杂”有一些优化会发生,但它们是特定的,很难预测。例如,应用程序中有更高的“需求”(即更大的缓冲区)操作系统将分配更多自己的资源来读取文件,这将加快文件访问速度。较大的预读缓冲区是加快速度的典型方式,但很难做出具体猜测。基本上,“就是这样”它的实现依赖于系统的其他部分,为什么它是这样工作的。BufferedInputStream是一些人已经编写的代码,不要再发明轮子。如果你需要它提供的功能,就使用它。谢谢你,伙计,我完全忘了这个方法可以在FIS中被覆盖