Search code examples
javafile-ioinputstreamfileinputstreambufferedinputstream

When would I use BufferedInputStream?


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?


Solution

  • 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.