当前位置: 首页 > 知识库问答 >
问题:

Java BufferedInputStream的幕后

南宫书
2023-03-14

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

  1. 比方说,有100个字节要从流中读取(文件作为源)。
  2. 如果没有缓冲,代码(BufferedInputStream的读取方法)必须进行100次读取(一次一个字节)。
  3. 使用缓冲,取决于缓冲区大小,代码使

在这种情况下,虽然被一个BufferedInputStream包装,底层流(例如FileInputStream)仍然必须一次读取一个字节。那么,缓冲的好处在哪里(不是对于只需要对缓冲区进行两次读取调用的代码,而是对于应用程序的性能)?

谢谢。

编辑:

我把它作为后续的“编辑”,而不是“评论”,因为我认为它在上下文中更适合这里和TL;为@Kayaman和我之间聊天的读者提供DR。

BufferedInputStream的读取方法说明(摘录):

作为额外的便利,它尝试通过重复调用底层流的read方法来读取尽可能多的字节。此迭代读取将继续,直到以下条件之一变为真:

The specified number of bytes have been read,
The read method of the underlying stream returns -1, indicating end-of-file, or
The available method of the underlying stream returns zero, indicating that further input requests would block. 

我深入代码,发现方法调用跟踪如下:

  1. BufferedInputStream-

以字节序列的形式读取子数组。

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

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

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

共有1个答案

谭修竹
2023-03-14

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

幸运的是,这将是非常低效的。它允许的BufferedInputStream使读取(字节[8192]缓冲区)调用的FileInputStream将返回数据块。

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

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

public synchronized int read() throws IOException {
    if (pos >= count) {
        fill();
        if (pos >= count)
            return -1;
    }
    return getBufIfOpen()[pos++] & 0xff;
}
 类似资料:
  • 我的有问题,当我在手机上启动应用程序时,它会显示约0.5秒的白色屏幕。扩展了,在中,我声明为启动器,肖像模式为。 代码: XML:

  • 在屏幕旋转后,虽然我在super.onCreate(null);,中传递null,但我得到了object返回的nullPointerException异常。我知道在传递savedInstanceState=null的同时必须销毁并重新创建活动,这意味着活动应该在旋转后开始,因为它是第一次开始,为什么在旋转后会出现此异常? onCreate()代码段,其中名为historyText的对象 Logca

  • screen 模块用于检索有关屏幕大小,显示,光标位置等的信息 进程: 主进程 渲染进程​ screen 是一个 EventEmitter. 注意: app模块必须用在 ready事件后. 注意: 在渲染进程或开发者工具栏中, window.screen 是一个预设值的 DOM属性, 所以 var screen = require('electron').screen 这样写的话是无效的. 创建一

  • 发布弹幕 调用地址 http://api.bilibili.cn/comment/post 需要 App Key 并验证登录状态(Access key);要求应用申请弹幕权限 参数 字段 必选 传递方式 类型 说明 mid true POST int 发布帐号(必须和 access_key 帐号一致) cid true POST int 视频ID playTime true POST float

  • 榜样很重要。 — 《机械战警》 Alex J. Murphy 警官 这份指南旨在提供一系列 Ruby on Rails 4 开发的最佳实践和风格惯例。本指南与社区驱动并制定的 Ruby 编码风格指南可以互为补充。 本文中的一些建议只适用于 Rails 4.0+ 版本。 你可以使用 Transmuter 来生成本文的 PDF 或 HTML 版本。 这份 Rails 风格指南推荐的是 Rails 的最

  • 1 前言 Libevent是一个轻量级的开源高性能网络库,使用者众多,研究者更甚,相关文章也不少。写这一系列文章的用意在于,一则分享心得;二则对libevent代码和设计思想做系统的、更深层次的分析,写出来,也可供后来者参考。 附带一句:Libevent是用c语言编写的(MS大牛们都偏爱c语言哪),而且几乎是无处不函数指针,学习其源代码也需要相当的c语言基础。 2 Libevent简介 上来当然要