当我会使用BufferedInputStream?

huangapple go评论64阅读模式
英文:

When would I use BufferedInputStream?

问题

为什么要用 BufferedInputStream 包装 FileInputStream,并使用 read(byte[20]),让 BufferedInputStream 在内部使用 8192 字节的缓冲以获得性能优势?

我可以直接使用 fileInputStream.read(byte[8192]),对吧?现在,我从未需要使用 BufferedInputStream。

什么情况下我会使用 BufferedInputStream?我有遗漏什么吗?当我可以通过 FileInputStream 进行大读取以获得更好的性能时,我从不希望进行较小的读取。在什么情况下会每次只读取 20 字节?

英文:

Why do I wrap FileInputStream with BufferedInputStream and use read(byte[20]) and let
BufferedInputStream buffer internally with 8192 bytes for performance benefits?

Instead I can use fileInputStream.read(byte[8192]) right? Now, I never require the usage of BufferedInputStream.

When would I use BufferedInputStream? Am I missing anything? I never wish to do smaller reads when I can get better performance benefits with large reads with FileInputStream. In what cases one does smaller reads like 20 bytes at a time?

答案1

得分: 2

你不需要。

BufferedInputStream仅在以下两种情况下是有用的:

  • 底层输入流(你传递给BufferedInputStream构造函数的那个流)是这样的,即小读取操作是低效的(也就是说,直到某个较大的大小,所有读取操作都需要相同的时间,因此小读取操作是低效的)。这通常适用于文件,有时适用于网络流。
  • 你实际上是打算进行小读取操作。

如果你的代码设置得可以一次读取一个缓冲区的数据,那很好。不要费心使用BufferedInputStream。这并不总是成立;例如,如果你在编写某种简单的二进制格式读取器,通常会执行大量的小读取操作(通常是.read(),它一次只读取一个字节)。

注意,.read(byte[])很难使用:如果你向这个方法传递一个大小为8192的字节数组,在这个方法中你不一定会读取全部8192字节,即使有8192字节可读:该方法会读取最佳数量的字节,保证至少读取1个字节(或者读取0个字节,并返回-1表示流结束,或者当然也可能会抛出异常),但它不能保证最大读取量,这使得除了基本的“位块传输”操作(在这种操作中,你只需读取全部数据并直接复制到其他地方)之外的几乎所有读取操作都变得复杂。

如果你在进行复制操作,注意in.transferTo(out)这个方法存在 - 一行代码就能搞定,甚至不需要创建缓冲区,而且它的效率已经是最高的了。

此外,如果你需要保证尽可能多地读取字节,还有.readNBytes.readFully方法可供使用。

英文:

You don't.

BufferedInputStream is a useful construct ONLY if BOTH of the following two things are true:

  • The underlying inputstream (the one you're passing to the BufferedInputStream constructor) is such that small reads are inefficient (as in, up to a certain large-ish size, all reads take the same time, so small reads are inefficient). This tends to be true for files and sometimes, network streams.
  • You are, in fact, intending to do small reads.

If your code is set up such that you can read one bufferload at a time, great. Don't bother with BufferedInputStream. This isn't always true; if for example you're writing some simple take on a binary format reader, you tend to do a ton of small reads. (usually, .read(), which reads up to one byte only).

Note that .read(byte[]) is hard to use: If you pass a 8192 sized byte array to this method, you do not neccessarily read in all 8192 bytes, even if there are 8192 to read: That method will read the optimal number of bytes, guaranteeing at least 1 byte read (or 0 bytes read and a return value of -1, indicating end-of-stream, or an exception of course), but it does not guarantee maximum read, which complicates just about every read job except basic 'blit' operations (where you just read it all and copy it straight into some other thing).

If you're doing the copy thing, note that in.transferTo(out) exsists - a one liner, you don't even have to make a buffer, and is going to be as efficient as you can be already.

There's also .readNBytes and .readFully if you need the guarantee that as many bytes as can be read, are read.

huangapple
  • 本文由 发表于 2020年8月18日 11:30:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63461456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定