Nov 25, 2011

Sources and sinks


This section focuses on sources and sinks. Code samples help you visualize how some of these classes work:
  • Byte arrays
  • Pipes
  • Sequences
  • Char arrays

Byte arrays
Let's head toward byte array territory. Are bytes going to come from a byte array? When an object of a ByteArrayInputStream is created, it is passed an array. You can then read bytes from that array as an InputStream .
ByteArrayOutputStream writes to a byte array. Bytes that are written to the output stream are added to an internal array. You may be wondering how you get to the byte array.
The toByteArray() method returns to you the byte array at any point in time. Also, a toString() method is available, which returns the byte array as a String.Therefore, the byte array can be either a source or a sink.  

Pipes in Java code
What is a pipe? A pipe is a means of communication between two threads of a Java program. One thread writes to a piped output stream and another thread reads from a piped input stream, which is connected to the piped output stream.
A pipe between two threads works like a pipe works between two processes in UNIX and MS-DOS. In those operating systems, the output from one process can be piped to the input of another process. For example, in MS-DOS, the command "dir | more" pipes the output of the "dir" command to the input of the "more" program.

Pipe: Example code
Although pipes are usually used with threads, this example simply writes data to a pipe and then reads it back later.
First, a PipedReader is constructed, then a PipedWriter that writes to that PipedReader.The  attributes are written to the pipe as Strings with a vertical bar as a delimiter and a new-line character  placed at the end. The entire contents of the PipedReader are read as a String and displayed.

Here is the example code:
import java.io.*;
import java.util.*;
class PipedExample
{
static BufferedReader system_in = new BufferedReader
(new InputStreamReader(System.in));
public static void main(String argv[])
{
PipedReader pr = new PipedReader();
PipedWriter pw = null;
try {
pw = new PipedWriter(pr);
}
catch (IOException e)
{
System.err.println(e);
}
// Create it {
// Read in three hotels
for (int i = 0; i < 3; i++)
{
Hotel a_hotel = new Hotel();
a_hotel.input(system_in);
a_hotel.write_to_pw(pw);
}
}
// Print it
{
char [] buffer = new char[1000];
int length = 0;
try
{
length = pr.read(buffer);
}
catch (IOException e)
{
System.err.println(e);
}
String output =new String(buffer, 0, length);
System.out.println("String is ");
System.out.println(output);
}
}
}
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(PipedWriter pw)
{
try
{
pw.write(name);
Integer i = new Integer(rooms);
pw.write(i.toString());
pw.write(location);
pw.write('backslash n');
// red font indicates that an actual backslash n (carriage return character)
// should be inserted in the code.
}
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;
}
}


Sequences
SequenceInputStream combines input streams and reads each input stream until the end. You can use SequenceInputStream to read two or three streams as if they were one stream. You can  concatenate streams from various sources, such as two or more files. To construct a SequenceInputStream , you can specify either two streams or an Enumeration, which represents a set of input streams. A program such as "cat" in UNIX would use something like this.
SequenceInputStream reads from the first underlying input stream that it is given. When the first one is exhausted, it opens the next input stream and reads that one. When that one is exhausted, it reads the next, and so on.
The user does not know when the input is transferred from one stream to the next stream;another byte is simply read. When all the input streams have been read, an EOF is received from the entire input stream.
 
Char arrays
Now let's explore Readers and Writers . The read and write methods input and output a character. Similar to ByteArrayOutputStream , a CharArrayWriter writes characters to a char array. As a character is written to a CharArrayWriter object, it's added to an array of characters whose size is automatically incremented.
At any point in time, we can get the character array that we have filled up. The toCharArray() method returns an array of characters. A CharArrayReader uses a character array as a source. Typically, the array is one that has been created with a CharArrayWriter object. With an alternative constructor, you can specify not only the array, but where to start in the array (an offset) and how many bytes to read (a length) before you return an EOF character.  

String: Example code
StringWriter works like CharArrayWriter .An internal StringBuffer  object is the  destination of the characters written. Methods associated with the class are getBuffer() , which returns the StringBuffer itself, and toString() , which returns the current value of the String.
StringReader works like CharArrayReader.It uses a String object as the source of the characters it returns. When a StringReader is created, you must specify the String that it is read from.
In this example, instead of writing to a pipe, we are going to write to a String . A StringWriter object is constructed. After the output is complete, we obtain the contents with toString() and print it out. This works like the previous example with PipedReader and PipedWriter, except a String is used to contain the data.

Here is the example code:
import java.io.*;
import java.util.*;
class StringExample
{
static BufferedReader system_in = new BufferedReader
(new InputStreamReader (System.in));
public static void main(String argv[])
{
StringWriter sw = new StringWriter();
// Create it
{
// Read in three hotels
for (int i = 0; i < 3; i++)
{
Hotel a_hotel = new Hotel();
a_hotel.input(system_in);
a_hotel.write_to_String(sw);
}
}
// Print it
{
String output = sw.toString();
System.out.println("String is ");
System.out.println(output);
}
}
}
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_String(StringWriter sw)
{
sw.write(name);
Integer i = new Integer(rooms);
sw.write(i.toString());
sw.write(location);
sw.write('backslash n');
// red font indicates that an actual backslash n (carriage return character)
// should be inserted in the code.
return true;
}
void debug_print()
{
System.out.println("Name :" + na
": Rooms : " + rooms + ": at :" + location+ ":");
}
static int to_int(String value)
{
int i = 0;
try
{
i = Integer.parseInt(value);
}
catch(NumberFormatException e)
{}
return i;
}
}

InputStreamReader
InputStreamReader reads bytes from an InputStream and converts them to characters. An InputStreamReader uses the default character encoding for the bytes, which is usually ASCII. If the bytes that are being read are ASCII bytes, only a byte at a time is used to form a character.
If the bytes are not ASCII, such as Chinese or another language, you want conversion to Unicode as well. Specific encoding of the byte stream is necessary, and the InputStreamReader converts it to Unicode. With an alternate constructor, you can specify the encoding of the bytes on the InputStream .

OutputStreamReader
OutputStreamWriter is similar to InputStreamReader . The output characters, which are in Unicode, are converted to the underlying format of the machine using an OutputStreamWriter. The converted characters are written to an OutputStream . The underlying default format is typically ASCII. However, you can state a specific encoding scheme with an alternate constructor. 



0 comments :

Post a Comment