Apr 12, 2012

Buffering


This section introduces buffering and covers the following topics:
·         BufferedInputStream and BufferedOutputStream
·         BufferedReader and BufferedWriter
·         New-line characters
·         Buffering input and output streams


What is buffering?
          Reading and writing to a file, getting data one byte at a time, is slow and painstaking. One way to speed up the process is to put a wrapper around the file and put a buffer on it.
Our BufferedInputStream is going to put a buffer onto an InputStream that is specified in the constructor. The actual data source is what you pass it as an InputStream .The BufferedInputStream reads large chunks of data from the InputStream. Then you read individual bytes or small chunks of bytes from the BufferedInputStream. The default buffer size is 512 bytes, but there's a constructor that allows you to specify the buffer size if you want something different.
To improve your efficiency, you read from the object of BufferedInputStream instead of reading directly from the underlying InputStream . And you won't have to go back to the operating system to read individual bytes.


BufferedOutputStream
     BufferedOutputStream extends FilterOutputStream . When you apply it to an OutputStream, you have a buffered output stream. Instead of going to the operating system for every byte you write, you have the intermediary that provides a buffer and you write to that.
When that buffer is full, it is written all at once to the operating system. And it is written automatically if the buffer gets full, if the stream is full, or if the flush() method is used. The flush() method forces any output buffered by the stream to be written to its destination. So for a BufferedOutputStream, you have tell it:
      ü  The output stream you are going to use
      ü  The buffer size if you don't like the default


BufferedReader and BufferedWriter
          A BufferedReader and a BufferedWriter act like BufferedOutputStream and BufferedInputStream , except they deal with reading and writing characters. For a BufferedReader , you specify an  underlying Reader and optionally a buffer size. For a BufferedWriter , you specify an underlying Writer and optionally a buffer size.
BufferedReader has one additional method, called readLine() , which allows us to simply read an entire line of characters from the underlying Reader.

BufferedReader: Example code
          If you've been using Java 1.0, the readLine() method was actually part of DataInputStream. Now you should be using a BufferedReader for readLine() , even though you can still do that with a DataInputStream.
A DataInputStream reads bytes but you are really reading characters when you read lines, so using readLine() and the BufferedReader is the preferred way.

Here is the example code:

import java.io.*;
import java.util.*;
class TextReaderWriterExample
{
static BufferedReader system_in = new BufferedReader
(new InputStreamReader(System.in));
public static void main(String argv[])
{
// Create it
{
try
{
FileOutputStream fos = new FileOutputStream("text.dat");
PrintWriter pw = new PrintWriter(fos);
for (int i = 0; i < 3; i++)
{
Hotel a_hotel = new Hotel();
a_hotel.input(system_in);
a_hotel.write_to_pw(pw);
}
pw.close();
}
catch(IOException e)
{
System.err.println(e);
}
}
// Now read it
{
try
{
FileReader fr = new FileReader("text.dat");
BufferedReader br = new BufferedReader(fr);
Hotel a_hotel = new Hotel();
while (a_hotel.read_from_br(br))
{
a_hotel.debug_print();
}
br.close();
}
catch(IOException e)
{
System.err.println(e);
}
}
}
}
class Hotel
{
private String name;
private int rooms;
private String location;
boolean input(BufferedReader in)
{
try
{
System.out.println("Name: ");
name = in.readLine();
System.out.println("Rooms: ");
String temp = in.readLine();
rooms = to_int(temp);
System.out.println("Location: ");
location = in.readLine();
}
catch(IOException e)
{
System.err.println(e);
return false;
}
return true;
}
boolean write_to_pw(PrintWriter pw)
{
pw.print(name);
pw.print('|');
pw.print(rooms);
pw.print('|');
pw.print(location);
pw.println();
return true;
}
boolean read_from_br(BufferedReader br)
{
try
{
String line = br.readLine();
if (line == null)
return false;
StringTokenizer st = new StringTokenizer(line, "|");
int count = st.countTokens();
if (count < 3)
return false;
name = st.nextToken();
String temp = st.nextToken();
rooms = to_int(temp);
location = st.nextToken();
}
catch(IOException e)
System.err.println(e);
return false;
}
return true;
}
void debug_print()
{
System.out.println("Name :" + name +
": Rooms : " + rooms + ": at :" + location+ ":");
}
static int to_int(String value)
{
int i = 0;
try
{
i = Integer.parseInt(value);
}
catch(NumberFormatException e)
{}
return i;
}

BufferedWriter
         As we mentioned, a BufferedWriter allows us to write to a buffer. It applies buffering to a character output stream, improving output efficiency by combining many small write requests into a single larger request.
This class has an interesting additional method that makes Java code portable. Most of the time, a new line is represented by a \n , but it may not be in all operating systems. Because of this, the Java language adds a method called newLine() .
Instead of outputting the character \n , you call newLine() and that outputs the appropriate new-line character for the particular operating system that you are running on. In most cases, this will be \n . The new-line character that is written is the one returned by passing line.separator to the getProperty() method in the System class.


Expressing a new line
          So you may ask, how does the Java language know how to express a new line for a particular operating system?
The Java newLine() method asks the system, "What is your new-line character?" In the Java language, this is called a system property. There is a System class with properties. When you say, "What's your new-line character?" by passing line.separator to the getProperty() method in the System class, you get an answer back. Depending on the platform, the new-line character can be a new-line character, a carriage-return character, or both.
The newLine() method, which is part of BufferedWriter , outputs the platform-dependent line separator to the stream by using such a call.


When to use BufferedWriter
         You typically use a BufferedWriter for your output. The only time you don't want to have a buffered output is if you are writing out a prompt for the user. The prompt would not come up until the buffer was full, so for those sorts of things you do not want to use buffering.


Buffering input and  output streams: Example code
            Here's an example of some code that shows the efficiency of buffering. Typically the read() method  on InputStreamReader or FileReader performs a read from the underlying stream.
It might be more efficient to wrap a BufferedReader around these Readers.With buffering, the conversion from byte to character is done with fewer method invocations than if the InputStreamReader read() method is called directly.
Likewise, the write() method on an OutputStreamWriter or FileWriter performs a write to the underlying stream. It can be more efficient to wrap a BufferedWriter around these Writers.

Here is the example code:

BufferedReader in=
newBufferedReader(newInputStreamReader(System.in));
Writer out=newBufferedWriter(new FileWriter("file.out");



0 comments :

Post a Comment