【问题标题】:Difference between InputStream.read(byte b) and BufferedInputStream in JavaJava 中 InputStream.read(byte b) 和 BufferedInputStream 的区别
【发布时间】:2019-05-27 01:16:48
【问题描述】:

我刚刚看到InputStream (link to Java 11 API) 类有一个方法read(byte[] b) 可以按字节读取数据流。这不就是一种“缓冲阅读”吗?

我进一步看到,BufferedInputStream (link to Java 11 API) 没有自己的read(byte[] b) 实现。它使用其父类FilterInputStream 的方法。

那么,InputStream 类是否也支持缓冲读取?和BufferedInputStream类的区别在哪里?

编辑

将“read(byte b)”更正为“read(byte[] b)”。

【问题讨论】:

  • InputStream 是一个抽象类,而不是一个接口!它确实提供了一个read(byte) 方法.. 而这个是一个缓冲区,不是吗?
  • 不同之处在于,当您使用 InputStream 读取一个或一个字节缓冲区时,它只会读取该字节或这些字节(最大),仅此而已。使用 BufferedInputStream 时,读取单个字节或字节缓冲区实际上会加载更大的字节块并将它们保存在内存中,以便下次读取。
  • 因此,如果您逐字节读取文件,或者使用 FileInputStream 从文件读取 10 个字节 x 10 个字节,您将进行大量文件系统读取,而如果您使用 BufferedInputStream,则第一次读取实际上会从文件系统中读取 8Kb 之类的内容,而下一次读取只会从内存缓冲区中读取,从而使其速度更快。简而言之,它的行为与您应该阅读的 javadoc 中描述的一样。

标签: java inputstream bufferedinputstream


【解决方案1】:

我假设您的意思是 byte[] b,而不是 byte b

根据 Javadoc,read(byte[] b) 的默认实现只是调用 read(b, 0, b.length)。由于此方法在 BufferedInputStream 中被覆盖,因此您可以说 read(byte[] b) 在所有意图和目的上也被覆盖。

BufferedInputStream 提供的附加功能是对markreset 方法的支持,这可以有效地让您在流中为某个点添加书签并从该书签中重新读取。缓冲区维护支持此操作所需的字节。否则,它只会读取当时可用的内容,而不进行任何缓冲。

【讨论】:

  • API 中没有提到,“read(byte[] b) 只是在调用read(b, 0, b.length)”?!我只能读到“InputStream 类的 read(b) 方法与:read(b, 0, b.length) 的效果相同”。
  • 好的。谢谢!但是,例如InputStream.read(byte[] b)byte[] b = new byte[1024] 也做了一种“缓冲读取”,从而一次从文件系统中读取 1024 个字节?
  • @mrbela 在您的问题下阅读了我的 cmets。 BufferedInputStream 使用 internal 缓冲区,无论您是一次读取一个字节还是一次读取 N 个字节,都使用该缓冲区;这就是使它成为缓冲流的原因。另请阅读 javadoc,它解释了同样的事情。
【解决方案2】:

所以InputStream 是一个接口,而 BufferedInputStream 是一个实现。 BufferedInputStream 环绕另一个 InputStream,如 FileInputStream 并缓冲数据。 BufferedInputStream 所做的是它在返回之前收集多个字节块,以便您可以一次读取更大的数据块以提高性能。

您可以查看此optimization example

【讨论】:

    猜你喜欢
    • 2012-04-06
    • 2012-05-13
    • 2017-01-18
    • 1970-01-01
    • 2021-11-05
    • 2014-12-05
    • 1970-01-01
    • 2020-06-12
    相关资源
    最近更新 更多