Way2Java

BufferedInputStream BufferedOutputStream

Using Buffers to Enhance the Performance

Buffering of streams increases the performance to higher extents of few thousand times. For buffering, two streams exist in java.io package in byte streams category – BufferedInputStream and BufferedOutputStream. These high-level classes are subclasses of FilterInputStream and FilterOutputStream and their functionality is to increase the performance with buffer. These streams give an implict system-defined buffer (generally, 2048 bytes) into which data is read and written. The buffer decreases the number of transfers between source file context area and destination file context area and thereby performance increases.

File Copying Using Buffer Streams: BufferedInputStream BufferedOutputStream

The following program uses high-level streams BufferedInputStream BufferedOutputStream to increase the performance.

import java.io.*;
public class InputAndOutputBuffering
{
  public static void main(String args[]) throws IOException
  {						// reading-side
    FileInputStream fistream = new FileInputStream("pqr.txt"); // a low-level stream
    BufferedInputStream bistream = new BufferedInputStream(fistream); // a high-level stream
						// wriring-side
    FileOutputStream fostream = new FileOutputStream("xyz.txt"); // a low-level stream
    BufferedOutputStream bostream = new BufferedOutputStream(fostream);  // a high-level stream
  
    int temp;
    while( ( temp = bistream.read() ) != -1 )
    {
      bostream.write(temp);   	
      System.out.print((char) temp);   	
    }
    bostream.close();  fostream.close();
    bistream.close();   fistream.close();
  }
}


Output screen on BufferedInputStream BufferedOutputStream

FileInputStream fistream = new FileInputStream("pqr.txt");
BufferedInputStream bistream = new BufferedInputStream(fistream);

For greater performance, the BufferedInputStream constructor is passed (chained) with an object of FileInputStream, fistream.

FileOutputStream fostream = new FileOutputStream("xyz.txt");
BufferedOutputStream bostream = new BufferedOutputStream(fostream);

Similarly, the BufferedOutputStream constructor is passed (chained) with an object of FileOutputStream, fostream.

How buffers increase performance?

A buffer works as a reservoir to store data. A buffer stands in between an input stream and output stream. The data is read and put in the buffer instead of sending immediately. When the buffer is full, the buffer is transferred. This decreases the number of execution control shiftings between input and output streams and thereby performance increases.

The size of buffer allocated depends on the underlying operating system. The size of buffer can be requested explicitly using overloaded constructor of BufferedInputStream as follows.

BufferedInputStream bistream = new BufferedInputStream(fistream, 6000);

In the above statement, a buffer is 6000 bytes is allocated by the OS.

Measuring the Performance with BufferedInputStream BufferedOutputStream

The speed of copying or time taken for copying can be measured reading system time before and after while loop as follows.

       long beforeLoop = System.currentTimeMillis();
       while((temp = bistream.read()) != -1 )
      {
        bostream.write(temp);   	
      }
      long afterLoop = System.currentTimeMillis();
      System.out.println("Time taken: " + (afterLoop – beforeLoop));

The static method, currentTimeMillis(), of System class returns the system time in milliseconds. Measuring the time before while loop and after while loop gives the time taken for copying. This style can be followed for any file copying program including FileToFile1.java. To have a noticeable difference, take a source file of atleast 2 lakhs bytes.

Using anonymous objects

        
      FileInputStream fistream = new FileInputStream("pqr.txt"); 
      BufferedInputStream bistream = new BufferedInputStream(fistream); 

Here, we use FileInputStream object only once just to open the file pqr.txt and fistream object is passed to BufferedInputStream() constructor. The above two statement can be replaced with one statement using anonymous objects.

        
      BufferedInputStream bistream = new BufferedInputStream(new FileInputStream("pqr.txt")); 

Similarly we can do with output streams also.

For basics of file copying, refer Semantics of File Copying.