首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java的BufferedInputStream幕后

Java的BufferedInputStream幕后
EN

Stack Overflow用户
提问于 2018-04-05 12:35:10
回答 1查看 262关注 0票数 1

首先,我理解缓冲作为包装器的概念,例如,FileInuptStream充当从底层流读取内容的临时容器(让我们使用读取场景),在本例中是FileInputStream

  1. 比方说,有100个字节可以从流(文件作为源)读取。
  2. 在没有缓冲的情况下,代码(readBufferedInputStream方法)必须进行100次读取(每次一个字节)。
  3. 通过缓冲,根据缓冲区大小,代码可以读取<= 100。
  4. 假设缓冲区大小为50。
  5. 因此,代码只读取缓冲区两次(作为源)来读取文件的内容。
  6. 现在,由于FileInuptStream是数据(包含100个字节的文件)的最终源(尽管由BufferedInputStream包装),它不需要读取100次才能读取100个字节吗?虽然,代码调用read方法的BufferedInputStream但是,调用被传递给FileInuptStreamread方法,该方法需要进行100个读取调用。这是我无法理解的观点。

IOW虽然被BufferedInputStream封装,但底层流(如FileInputStream)仍然需要一次读取一个字节。那么,缓冲的好处是什么(不是对于只需要两个读调用来缓冲的代码,而是对应用程序的性能)?

谢谢。

编辑:

我把它作为一个后续的‘编辑’而不是‘评论’,因为我认为它的上下文更适合这里,作为一个TL;博士之间的@Kayaman和我之间的聊天读者。

朗读方法BufferedInputStream说(节选):

另外,为了方便起见,它试图通过反复调用底层流的read方法来读取尽可能多的字节。此迭代读取将继续进行,直到下列条件之一变为真为止: 已读取指定数量的字节,底层流的读取方法返回-1,表示文件结束,或者底层流的可用方法返回零,指示进一步的输入请求将被阻塞。

我钻研了代码并找到了如下所示的方法调用跟踪:

  1. BufferedInputStream -> read(byte b[])作为一个我希望看到缓冲在运行中。
  2. BufferedInputStream -> read(byte b[], int off, int len)
  3. BufferedInputStream -> read1(byte[] b, int off, int len) -私有
  4. FileInputStream -read(字节b[],int off,int len)
  5. FileInputStream -> readBytes(byte b[], int off, int len) -私有的和本地的。方法描述来自源代码-

将子数组读取为字节序列。

read1中调用BufferedInputStream (上面提到的#4)处于无限for循环中。它在上述read方法描述的摘录中提到的条件下返回。

正如我在OP(#6)中提到的,调用似乎是由一个与API方法描述和方法调用跟踪相匹配的底层流处理的。

问题仍然存在,如果本机API调用- readBytes of FileInputStream一次读取一个字节并创建一个这些字节的数组返回呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-05 12:38:19

底层流(如FileInputStream)仍然必须一次读取一个字节。

幸运的是,没有,这将是非常低效的。它允许BufferedInputStreamFileInputStream进行read(byte[8192] buffer)调用,这将返回一块数据。

如果您想读取单个字节(或不读取),那么它将有效地从BufferedInputStream's内部缓冲区返回,而不必降到文件级别。因此,BI的存在是为了减少我们从文件系统进行实际读取的时间,当完成这些操作时,即使最终用户只想读取几个字节,它们也是以高效的方式完成的。

从代码中可以很清楚地看出,BufferedInputStream.read()做的是而不是直接委托给UnderlyingStream.read(),因为这将绕过所有的缓冲。

代码语言:javascript
复制
public synchronized int read() throws IOException {
    if (pos >= count) {
        fill();
        if (pos >= count)
            return -1;
    }
    return getBufIfOpen()[pos++] & 0xff;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49672561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档