2

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?

3
  • You would use it if you are reading smaller chunks, e.g. ints with DataInputStream.readInt(), or if you are wrapping a Socket where you don't know how much data is really available at each moment. Reading 8192 bytes at a time is the exception rather than the rule. And even if you are doing that, there is no penalty to using BufferedInputStream on top. In short, you may as well use it always. Commented Aug 18, 2020 at 3:53
  • Or even if you were reading this stream with large pauses in between the reads. A buffered stream could read the characters in advance, so they'd be ready for you. Commented Aug 18, 2020 at 4:07
  • @ Marquis of Lorne. Thanks! Can you give some real world examples for smaller reads which is really convincing? Commented Aug 18, 2020 at 4:56

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Can you give few real world examples of smaller reads? I don't get when I will be using it.
Take java's class file format. A constant in the constant pool starts with 2 bytes that identify the type of constant. Then you read some number of bytes, depending on that 'type' value. Easiest way is to just.. read 2 bytes, follow a switch() block into the appropriate 'read this type of constant' code. if it is an int constant, that would read 4 bytes only. and so on.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.