BufferedInputStream - sample program in Java

By: Daniel Malcolm Viewed: 153322 times  Printer Friendly Format    


Buffering I/O is a very common performance optimization. Java's BufferedInputStream class allows you to "wrap" any InputStream into a buffered stream and achieve this performance improvement.

BufferedInputStream has two constructors:

BufferedInputStream(InputStream inputStream)
BufferedInputStream(InputStream inputStream, int bufSize)

The first form creates a buffered stream using a default buffer size. In the second, the size of the buffer is passed in bufSize. Use of sizes that are multiples of memory page, disk block, and so on can have a significant positive impact on performance. This is, however, implementation-dependent. An optimal buffer size is generally dependent on the host operating system, the amount of memory available, and how the machine is configured. To make good use of buffering doesn't necessarily require quite this degree of sophistication. A good guess for a size is around 8,192 bytes, and attaching even a rather small buffer to an I/O stream is always a good idea. That way, the low-level system can read blocks of data from the disk or network and store the results in your buffer. Thus, even if you are reading the data a byte at a time out of the InputStream, you will be manipulating fast memory over 99.9 percent of the time.

Buffering an input stream also provides the foundation required to support moving backward in the stream of the available buffer. Beyond the read() and skip() methods implemented in any InputStream, BufferedInputStream also supports the mark() and reset() methods. This support is reflected by BufferedInputStream.markSupported() returning true.

The following example contrives a situation where we can use mark() to remember where we are in an input stream and later use reset() to get back there. This example is parsing a stream for the HTML entity reference for the copyright symbol. Such a reference begins with an ampersand (&) and ends with a semicolon (;) without any intervening whitespace. The sample input has two ampersands to show the case where the reset() happens and where it does not.

// Use buffered input.
import java.io.*;
class BufferedInputStreamDemo {
public static void main(String args[]) throws IOException {
String s = "This is a © copyright symbol " +
"but this is &copy not.\\n";
byte buf[] = s.getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(buf);
BufferedInputStream f = new BufferedInputStream(in);
int c;
boolean marked = false;
while ((c = f.read()) != -1) {
switch(c) {
case '&':
if (!marked) {
f.mark(32);
marked = true;
} else {
marked = false;
}
break;
case ';':
if (marked) {
marked = false;
System.out.print("(c)");
} else
System.out.print((char) c);
break;
case ' ':
if (marked) {
marked = false;
f.reset();
System.out.print("&");
} else
System.out.print((char) c);
break;
default:
if (!marked)
System.out.print((char) c);
break;
}
}
}
}

Notice that this example uses mark(32), which preserves the mark for the next 32 bytes read (which is enough for all entity references). Here is the output produced by this program:

This is a (c) copyright symbol but this is &copy not.

Caution: Use of mark() is restricted to access within the buffer. This means that you can only specify a parameter to mark() that is smaller than the buffer size of the stream.

This tutorial is an extract from the "The Complete Reference Part 2 by Herbert Schildt".



Most Viewed Articles (in Java )

Latest Articles (in Java)

Comment on this tutorial