BufferInputStream vs ByteArrayInputStream

Tags: , ,



Here are three ways to read an entire file into memory before processing it:

Approach A:

fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);

Approach B:

ByteArrayInputStream bi =
    new ByteArrayInputStream(
        org.apache.commons.io.FileUtils.readFileToByteArray(file))

Approach C:

File file = new File(yourFileName);
RandomAccessFile ra = new RandomAccessFile(yourFileName, "rw"):
byte[] b = new byte[(int)file.length()];
try {
    ra.read(b);
} catch (Exception e) {
    e.printStackTrace();
}

Why would I prefer one approach over another?
Are there any specific use-cases that call for one approach over another?
Why not use a fixed-length byte[] instead?

Answer

Unless you need anything special in terms of capabilities (e.g. random access), an InputStream wrapped into a BufferedInputStream is the general purpose choice for reading sequentially from any kind of data source that provides a streaming capability.

This will provide reasonable performance (through buffering), the code is generic in that it can process any stream, and also very important – the size of processable streams isn’t limited by the available heap memory by this idiom.

So unless you have a very compelling reason to code against a special case API, use a standard InputStream and wrap it as needed.


EDIT: In response to the questions asked in the comment by @IUnknown:

  1. What is the approach in the case of a random access – I thought BufferedInputStream is the preferred solution even in that case?

There is no generic interface for random access. You thought wrong. You could at least be so courteous to study the basics of basics: http://docs.oracle.com/javase/tutorial/essential/io/

  1. the size of processable streams isn’t limited by the available heap memory – the buffer must be having a limit.Are you saying that the internal array automatically re-sizes if its filled up while reading?

Again, thats covered in the basics (see above). With ByteArrayInputStream you need a byte[] to hold the entire stream. How’s that not limited by memory? (even worse, its also hard capped by max array size).

  1. Is there any difference in the buffer behavior between a Buffered stream and a ByteArray stream – I thought they are backed up by similar buffer behaviour

I don’t know what to say. You thought wrong. Set aside the basic facts they both extend InputStream and somehow use a byte array internally (and technically either could be implemented without using any array, its just the most natural way to do it). They have nothing in common. A BufferedStream hold a small dynamic portion of another stream. ByteArrayInputStream was covered in 2.

Advice: People here will gladly advise you on which tool to use for which job. But don’t expect to be spoon-fed. Show some effort, stackoverflow isn’t a tutoring site. Stop “thinking” and start “learning” – the tutorials are out there and have been since the dawn of the language.



Source: stackoverflow