Buffered Streams – A Booster For Byte and Character Streams

Buffered Streams are used to speed up the input output operations by simply creating a buffer space of some specific size so that we don’t have to access the disk every time we perform I/O operation, which is a time and resource consuming process. In absence of buffer storage each I/O operation is handled by the operating system.

These buffers are used to minimize the direct communication with the storage system or the networks.

These Buffered Streams acts as a wrapper for the Character stream and the Byte streams and allow them to read and write data from and to the buffer. This on the other hand reduced the costly operations like disk access, network access etc as it reads and writes data in chunks(i.e. a large amount of data at once).

For Example – Consider a bag which contains 100 candies and is located 20 meters away from you. You can not carry the whole bag and you have to distribute these candies to 100 students. So one way is that you travel each time to the bag take out one candy and give it to the child( similar to simple input output operations). Another way is you carry some amount of candies every time you go to bag may be 10, 20 ,30 etc depending on your capacity to carry (this capacity is the size of the buffer and this process is somewhat similar to Buffered Streams). Now you can clearly understand that by creating a buffer of candies we can save a lot of work and even our process completes in much lesser time. Same is the case with Buffered Streams in Java.

Streams- inserting Data into the stream
Streams- inserting Data into the stream

In our discussion of Character Streams and Byte Streams we have used simple I/O operations and we can convert those programs simply by wrapping them in buffered classes and used their methods.


Wrapper Classes for Byte Streams
  1. BufferedInputStream
  2. BufferedOutputStream

Wrapper Classes for Character Streams
  1. BufferedReader
  2. BufferedWriter

Read/Write File Using BufferedStream
  • Below example uses Byte Streams as the basic input and output stream.

Note :- Keep an eye on all the comments.

package codingeekExamples;

import java.io.*;

public class BufferedStreamExample {

	public static void main(String[] args) {

		//If you are using an older version and not using try with resources
		//than don't forget to close the streams in the finally block.
		try (
		// Byte Streams
		// Either use a fully qualified name of the image or just use the name
		//and ensure that the image is in classpath.
		InputStream inputStream = new FileInputStream("C:\\Users\\Public\\Pictures\\Sample Pictures\\Koala.jpg");
				OutputStream outputStream = new FileOutputStream("output.jpg");

				// Buffered Streams
				// Enveloping Byte Streams into Buffered Streams
				BufferedInputStream bufferIn = new BufferedInputStream(inputStream);
				BufferedOutputStream bufferOut = new BufferedOutputStream(outputStream)) {

			// This array stores the data read in the form of Bytes.
			byte[] buffer = new byte[1024];

			// Looping till we reach the end of file i.e value returned is -1
			while (bufferIn.read(buffer) != -1) {

				// writing to output buffer
				bufferOut.write(buffer);
			}
			System.out.println("File copied successfully");
		} catch (FileNotFoundException e) {
			System.out.println("Input file is not found");
		} catch (IOException e) {
			System.out.println("Error in Reading and writing operations");
		}
	}
}
Output:-
File copied successfully

  •  Now this example uses Character Streams as the basic input and output stream. Unlike Byte Streams this can be used only to read and write character files.

Note :- Keep an eye on all the comments.

package codingeekExamples;

import java.io.*;

public class BufferedStreamExample {

	public static void main(String[] args) {

		/*
		 * If you are using an older version and not using try with resources
		 * than don't forget to close the streams in the finally block.
		 */
		try (

				/*
				 * Character Streams Either use a fully qualified name of the image or
				 * just use the name and ensure that the image is in classpath.
				 */
				Reader reader = new FileReader("input.txt");
				Writer writer = new FileWriter("output.txt");

				/*
				 * Buffered Streams Enveloping Byte Streams into Buffered
				 * Streams
				 */
				BufferedReader bufferReader = new BufferedReader(reader);
				BufferedWriter bufferWriter = new BufferedWriter(writer)
			) {

			String read = "";

			// Looping till we reach the end of file i.e value of read becomes null
			while (null != (read=bufferReader.readLine())) {

				bufferWriter.write(read); // writing to output buffer
				bufferWriter.write("\n"); // This ensures proper formatted output text
			}
			System.out.println("File copied successfully");
		} catch (FileNotFoundException e) {
			System.out.println("Input file is not found");
		} catch (IOException e) {
			System.out.println("Error in Reading and writing operations");
		}
	}
}
Output:-
File copied successfully

Note :- By this method you can not achieve internationalization. For that you have to use Byte stream wrapped into Character stream and then finally wrapped in Buffer stream.

Source :-
Oracle

Keep Learning. Happy Learning. :)

  • Rohit Mukherjee

    Hi Hitesh Garg,

    I need help with “Java Object Typecasting”, i am not able to understand the concept properly can you help me with that.

    • hiteshgarg21

      Hi @Rohit

      thank you for writing to us. I hope we are quite explanatory in our posts that drive you to ask this. Share post and answer if you like. Let me try to explain you a bit.

      Simply saying we do typecasting so as to convert an object of one type into an object of another type to access the features that are otherwise unavailable or hidden in OOPS sense because of inheritance and polymorphism.

      It’s easy that Super class reference variable is pointing to Sub Class object but catch here is that there is no way for Java compiler to know that a Super class variable is pointing to Sub Class object. Which means you can not call method which is declared on sub class. In order to do that, you first need to cast the Object back into its original type

      Base b = new Derived(); //reference variable of Base class points object of Derived class
      Derived d = b; //compile time error, requires casting – This is why we need typecasting
      Derived d = (Derived) b; // type casting Base to Derived

      You can go to the following likn for better understanding http://javarevisited.blogspot.in/2012/12/what-is-type-casting-in-java-class-interface-example.html