# Chapter 12

# The Java I/O and Utility Class Libraries

### CONTENTS

- Introduction to the java.io Package
- How Java's I/O System Works
- Java Input Streams
  - The InputStream Class
  - More on the InputStream Class and Its Subclasses
  - The ByteArrayInputStream Class
  - The FileInputStream Class
  - The SequenceInputStream Class
  - The StringBufferInputStream Class
- Java Output Streams
  - The OutputStream Class
  - Miscellaneous I/O Classes
- The java.util Package
  - The Bitset Class
  - The Date Class
  - The Dictionary Class
  - The Hashtable Class
  - The Properties Class
  - The Random Class
  - The Vector Class
  - The Stack Class
  - The StringTokenizer Class
- Summary

This chapter continues our adventure of exploring the Java packages. Two packages are covered here: `java.io` and `java.util`. The `java.io` package contains interfaces, classes, and methods that facilitate input and output of data to applets and applications. The `java.util` package is a mixed bag of utilities useful in writing Java programs. Its classes are used to manipulate dates, create hash tables, and directly manipulate stacks of objects, among other things.

## Introduction to the `java.io` Package

The Java input and output package-`java.io-`is used to implement streams. Streams are covered in Chapter 8, "Tying It All Together: Threads, Exceptions, and More;" refer to that chapter if you have difficulty with some of the examples or information in this chapter. Here I cover the classes and methods that manipulate streams.

Streams are used to move groups of data from point A to the Java application or from the Java application to point B. At its simplest, transmitted data is in the form of a stream of bytes without formatting or identification. It is up to the Java application to reformat and reinterpret it in such a way that the data makes sense to the application.

Data traditionally has been stored in files on a disk somewhere. Moving data was a simple matter of opening a file, copying the data to memory, copying the needed portions from memory, and moving the data from memory to a new disk location under a new filename on a system that controlled all the steps of the process.

That scenario is certainly not the case these days. Data can be generated by users on a local network and loaded on a distributed system. It can come from just about any system in the world over the Internet; and from disk, tape, CD-ROM, and so on. The source of the data may be running any number of operating systems, which means that the data might be in a format foreign to the system running the Java application. Therefore, Java must be able to interpret data in many formats from many sources. It must be adaptable enough to handle this data without requiring code changes if the data stream origin changes. The classes and methods in `java.io` help make this happen.

## How Java's I/O System Works

Remember that the whole idea behind Java is to provide a non-platform-specific application language. This includes the movement and interpretation of data. The classes and methods in the `java.io` package allow great flexibility in sending and receiving data.

Java provides control over the flow of input streams using `mark` and `reset` (discussed in Chapter 8). However, not all forms of Java I/O allow the use of `mark` and `reset`.

The following sections discuss the various ways to move data in Java. Pick the one that best suits your needs, because each has advantages and disadvantages.

## Java Input Streams

Input streams are streams of data that arrive from a source and are loaded into Java. Java doesn't care about the data's origins; it only cares about the data being available to send to the Java application. All the input stream classes throw the exception `IOException`. (Refer to the section in Chapter 8 called "Exceptions" for more information.)

All the input stream classes are based on the abstract class `InputStream`. The next section discusses the methods associated with that class.

### The `InputStream` Class

`InputStream` is the abstract class that contains all the possible types of inputs to Java. Its subclasses use most or all of its methods. These methods are discussed in the "Input Streams" section of Chapter 8, but let's go over them again.

#### read

All of `InputStream`'s subclasses can read data from an input stream. These reads are based on blocking, which allows the Java application to wait if the input stream is not continuous.

#### skip

The `skip` method is used to bypass a fixed number of bytes of an input stream. This method is available to all of `InputStream`'s subclasses.

#### close

The `close` method is used to shut down an input stream that is no longer being used. Files are closed automatically when the Java garbage collector finalizes and closes them. However, it is important to manually close the stream if the file is going to be opened again soon. You can't know exactly when the garbage collector will finally close the stream, and Java will not reopen an already open file.

#### available

The `available` method is used to determine whether the data is ready to be sent. Remember, the program will block if the data is not ready but a `read` request has been sent. If you put the `read` request in a separate thread, it won't matter if the block occurs; in that case it is not necessary to use `available`. Make sure, however, that this makes sense in the application. Using separate threads is not advisable if the whole application relies on the data to be sent.

The `available` method is not available for all subclasses of `InputStream`.

#### mark, markSupported, and reset

The `mark` method marks a point in an input stream to return to later. The `markSupported` method makes sure that the type of input stream allows `mark`. The `reset` method returns to the point marked by `mark`. These methods are not supported in all the subclasses of `InputStream`.

### More on the `InputStream` Class and Its Subclasses

The subclasses of `InputStream` are `ByteArrayInputStream`, `FileInputStream`, `FilterInputStream`, `PipedInputStream`, `SequenceInputStream`, and `StringBufferInputStream`. Each is discussed in detail in the following sections.

#### The `FilterInputStream` Class

`FilterInputStream` has four subclasses: `BufferedInputStream`, `DataInputStream`, `LineNumberInputStream`, and `PushbackInputStream`. These subclasses work in a unique way with `FilterInputStream`: They allow it to control the flow of a file to them. `FilterInputStream` does nothing by itself.

Think of `FilterInputStream` as providing the structure of the pipe for the flow of data while its subclasses chop the data up into small, usable bits. Picture `FilterInputStream` as the a pasta maker that squeezes out the dough while the subclass turns it into spaghetti or fettucine or lasagna noodles. The data is the dough. It is also possible to change the "mold," or subclass, midstream, just as you would change the form on the pasta maker. However, you don't have to stop the machine while changing the form; the data still flows through.

`FilterInputStream`'s subclasses are widely used in writing Java programs. Following is a discussion of the subclasses. (Read the online documentation for a full list of each subclass's capabilities.)

##### The `BufferedInputStream` Class

> `BufferedInputStream` is a subclass of `FilterInputStream`. It implements all the methods defined in the superclass `InputStream`.

Note
`BufferedInputStream` is the only class that uses `mark` and `reset` correctly.

> Another key attraction to using `BufferedInputStream` is that it creates a read buffer, which is an array of bytes. This read buffer smooths out the stream of data so that reading can be continuous, as opposed to waiting for the input to reach the stream. The size of the buffer and the size of the reads can be controlled through `BufferedInputStream`'s methods. Listing 12.1 is an example of `BufferedInputStream` and `BufferedOutputStream`.

> Listing 12.1. An example of BufferedInputStream and BufferedOutputStream.

> `/* Notes:
> ` This class implements buffered file input/output streams by extending
> class BufferedInputStream. This is not a complete implementation of all
> of FileInputStream (not enough constructors, or getFd()).
> The main example simply copies the first 128 bytes of file one to
> file two, then resets file one to the beginning and proceeds to copy
> all of file one to file two. This has no practical purpose, but does
> demonstrate that a BufferedFileInputStream class has been created that
> implements mark and reset, which FileInputStream does not support.
> Syntax:
> MyMain <source file> <dest file>
> */
> import java.io.*;
> public class MyMain {
> public static void main (String args[]) {
> // declare buffered file input stream
> BufferedFileInputStream bfis;
> // declare buffered file output stream
> BufferedFileOutputStream bfos;
> // declare buffer
> byte buf[];
> int cnt;
> // create 1024 byte buffer
> buf = new byte[1024];
> try {
> //create buffered file input stream using first argument
> //on command line
> bfis = new BufferedFileInputStream(args[0]);
> //create buffered file output stream using second argument
> //on command line
> bfos = new BufferedFileOutputStream(args[1]);
> // mark beginning of file to be buffered for 128 bytes
> bfis.mark(128);
> // read 128 bytes from source file
> bfis.read(buf,0,128);
> // write buffered bytes to dest file
> bfos.write(buf,0,buf.length);
> // reset to beginning of file
> bfis.reset();
> // loop through source file reading 1024 bytes at a time
> while (bfis.read(buf,0, 1024) != -1) {
> // write buffer to dest file
> bfos.write(buf, 0, buf.length);
> }
> // close source file
> bfis.close();
> // close source file
> bfos.close();
> }
> // catch file not found errors (do nothing)
> catch (FileNotFoundException e){}
> // catch IO errors (do nothing)
> catch (IOException e){}
> }
> }
> // declare new class that extends buffered input stream
> class BufferedFileInputStream extends BufferedInputStream {
> // declare file input stream
> FileInputStream f;
> // override buffered input stream constructor
> public BufferedFileInputStream(String filename) throws IOException {
> // create buffered input stream using file input stream
> super(new FileInputStream(filename));
> }
> }
> // declare new class that extends buffered output stream
> class BufferedFileOutputStream extends BufferedOutputStream {
> // override buffered output stream
> public BufferedFileOutputStream(String filename) throws
> IOException {
> // create buffered output stream using file output stream constructor
> super(new FileOutputStream(filename));
> }
> `}`

##### The `DataInputStream` Class

> `DataInputStream` is a subclass of `FilterInputStream`. It also implements the `DataInput` interface. Look at the following list of methods in `DataInputStream`, and the major use of the class becomes obvious (note that these same methods are used by the class `RandomAccessFile`):

> `readBoolean
> readByte
> readChar
> readDouble
> readFloat
> readInt
> readLine
> readLong
> readShort
> readUTF
> readUnsignedByte
> readUnsignedShort`

> These methods are used to read primitive data types. Remember primitive data types from Chapter 6, "Fundamentals of the Java Language"? This class interprets primitive data types across platforms and makes them accessible to Java.

##### The `LineNumberInputStream` Class

> `LineNumberInputStream` is a subclass of `FilterInputStream`. This class keeps track of line numbers, which could be used to mark and reset data streams. `LineNumberInputStream` also can be used to nest the handling of input streams so that it is possible to simultaneously read the stream for other purposes and keep track of line numbers.

##### The `PushbackInputStream` Class

> `PushbackInputStream` is a subclass of `FilterInputStream`. It creates a one-byte input buffer that allows the input stream to retreat one byte after it has been read. This makes it possible to test the next byte before taking action. Listing 12.2 is an example of `PushbackInputStream`.

> Listing 12.2. An example of `PushbackInputStream`.

> `/* Notes:
> ` This class implements a word search program. A word is defined as a
> character string. It considered a word instead of a substring if the
> word is followed by a space. The algorithm works its way through the
> input stream. If it actually finds a word, it pushes the space
> that delimited the word back on the stream so that it can be processed
> if needed by other algorithms.
> The main example accepts a string to search for and a filename to
> search in as command line arguments. It will print "Word found" if
> the word is successfully found, and "Word not found" if it does not.
> Syntax:
> MyMain <string to search for> <file to search>
> */
> import java.io.*;
> public class MyMain {
> public static void main (String args[]) {
> // declare FindWord object
> FindWord f;
> try {
> // create FindWord object by passing it a FileInputStream object.
> //File opened in second argument on command line.
> f = new FindWord(new FileInputStream(args[1]));
> // find word specified as first argument on command line.
> if (f.find(args[0]))
> // print out found message if word is found
> System.out.println("Word found");
> else
> // print out not found message if word not found
> System.out.println("Word not found");
> }
> // handle file not found exceptions
> catch(FileNotFoundException e) {
> System.err.println("ERROR: File not found");
> System.err.println(" file = " + args[1]);
> System.exit(2);
> }
> }
> }
> // declare class FindWord
> class FindWord {
> // declare PushbackInputStreamObject
> PushbackInputStream pbs;
> // declare FindWord constructor
> public FindWord(InputStream in) {
> // create pushback stream using passed in input stream
> pbs = new PushbackInputStream(in);
> }
> // declare method to find word in stream
> public boolean find (String word) {
> // declare buffer to be used in stream reads
> byte buf[];
> int i = 0;
> // declare booleans for word found and end-of-file
> boolean found, EOF;
> // create one byte array needed by stream read
> buf = new byte[1];
> // initialize word found variable to false
> found = false;
> // initialize end-of-file variable to false
> EOF = false;
> // declare string buffer so a space can be appended to search word
> StringBuffer sbWord;
> // create string buffer initialized to search word followed by a space
> sbWord = new StringBuffer(word + " ");
> // label for labeled continue inside loop
> startOver:
> // loop waiting for word found or end of file
> while ((! found) && (! EOF)) {
> // loop for matching search word to chars in input stream
> for (i=0; i < sbWord.length(); i++) {
> try {
> // read char from stream checking for EOF
> if (pbs.read(buf,0,1) == -1) {
> // set EOF boolean if EOF reached
> EOF = true;
> }
> // compare stream char to search word char
> if ((char)buf[0] != sbWord.charAt(i)) {
> // if different continue in OUTER while loop
> continue startOver;
> }
> }
> // handle IO exceptions
> catch(IOException e){
> // exit application if IO error occurred
> System.exit(3);}
> }
> // word found if this point reached, push space back on stream
> try {pbs.unread(buf[0]);}
> // handle IO exceptions
> catch(IOException e){
> // exit application if IO error occurred
> System.exit(4);}
> // return true since word found
> return(true);
> }
> // return false since word not found
> return(false);
> }
> `}`

### The `ByteArrayInputStream` Class

`The ByteArrayInputStream` class extends the `InputStream` class. This class is used to create an input stream from a buffer. The input stream is accessed in the number of bytes set by the programmer. The flow of data to the input stream is controlled by three variables:

- `buf`-The buffer where data is stored
- `Count`-The number of bytes to use in the buffer
- `Pos`-The current position in the buffer

`ByteArrayInputStream` allows use of the `reset` method, which resets the input stream back to the beginning. There is no `mark` method to mark a specific place in the stream.

### The `FileInputStream` Class

`The FileInputStream` class extends the `InputStream` class. This class allows Java to read files. This will work only with sequential files, not with hash tables or indexed files. The file itself must be accessible to Java.

Be sure to explicitly close the file input stream if there are to be subsequent accesses to it after the end of file has been reached. `mark` and `reset` are not available to `FileInputStream`. The only way to return to a position is to skip to it and then read to find a desired piece of data. There is no way to know exact positions in the file directly with `FileInputStream`.

Refer to the section in Chapter 8 titled "Input Streams" for an example of the use of `FileInputStream`.

### The `SequenceInputStream` Class

`SequenceInputStream` allows multiple files to be read in sequence and converted into a single stream. The first input is read through to the end of file, then the next file is read, and so on. The output is a byte array. The only methods available are `read` and `close`.

One reason to use `SequenceInputStream` is to receive multiple inputs, create one input stream, and pass the stream off to another class that has more data-manipulation methods available.

### The `StringBufferInputStream` Class

`StringBufferInputStream` is used to create an input stream from a buffer. The input stream is an array of string characters. The flow of data to the input stream is controlled by three variables:

- `buf`-The buffer where data is stored
- `Count`-The number of characters to use in the buffer
- `Pos`-The current position in the buffer

This is similar to `ByteArrayInputStream`; the only difference is that `ByteArrayInputStream` inputs the stream as an array of bytes, whereas `StringBufferInputStream` creates the input stream as an array of string characters. With `StringBufferInputStream`, you can use the `reset` method, which resets the input stream to the beginning. There is no `mark` method to mark a specific place in the stream.

## Java Output Streams

Once again, refer to Chapter 8 for a detailed discussion of output streams. I will do only a quick review here. This section discusses the `java.io` package and its output stream classes.

Output streams are data streams generated by a Java application or applet for use elsewhere. There are several ways to format the data for output: It can be piped, buffered, printed to a screen, stored in an array of bytes, or output to a file. Output stream classes perform the output duty.

All the output stream classes are based on the abstract class `OutputStream`. The next section discusses the methods associated with `OutputStream`.

### The `OutputStream` Class

`OutputStream` is the abstract class that contains all the possibilities of output from Java. Its subclasses are `BufferedOutputStream`, `ByteArrayOutputStream`, `DataOutputStream`, `FileOutputStream`, `FilterOutputStream`, `PipedOutputStream`, and `PrintStream`.

`OutputStream`'s subclasses use most or all of its methods. These methods are discussed in Chapter 8, but a quick review never hurts.

##### `write`

> The `write` method is used to write data to a stream. It varies for each class in its output. All `write` methods are the same in that they block, or wait, for the receiving device to catch up. All `write` methods also throw the exception `IOException`.

> See the section titled "Input Streams" in Chapter 8 for an example of `write`.

##### `flush`

> The `flush` method is used to force any data buffered for the output stream to be written to the output device. This is the only way to override a block. This also may be the only way to write data if the receiving device requires it.

##### `close`

> The `close` method closes an output stream. It is identical in logic to the `close` used for input streams. The Java garbage collector schedules a cleanup to the output streams when an applet or application closes. Be sure to manually call `close` if the application can't wait for the garbage collector.

#### The `FilterOutputStream` Class

`FilterOutputStream` has three subclasses: `BufferedOutputStream`, `DataOutputStream`, and `PrintStream`. These subclasses work in a unique way with `FilterOutputStream`; they allow it to control the flow of a file to them. `FilterOutputStream` does nothing by itself. (This is the output equivalent to `FilterInputStream`.)

Following is a discussion of the subclasses. Read the online documentation for a full list of each subclass's capabilities.

##### The `BufferedOutputStream` Class

`BufferedOutputStream` implements all the methods defined in superclass `OutputStream`. `BufferedOutputStream` uses `flush` and can create a nested stream to allow other output streams to flush.

Another key attraction to using `BufferedOutputStream` is that it creates a write buffer in the form of an array of bytes. This write buffer smooths out the stream of data so that writing can be continuous, as opposed to waiting for the output to reach the stream. The size of the buffer and the size of the writes can be controlled through `BufferedOutputStream`'s methods.

##### The `DataOutputStream` Class

> `DataOutputStream` also implements the `DataOutput` interface. It is the inverse of `DataInputStream` and is used to write primitive data types. Following is a list of associated methods:

> `writeBoolean
> writeByte
> writeChar
> writeDouble
> writeFloat
> writeInt
> writeLine
> writeLong
> writeShort
> writeUTF
> writeUnsignedByte
> writeUnsignedShort`

> `DataOutputStream` is used with `BufferedInputStream` to pull and push primitive data types across platforms.

##### The `PrintStream` Class

> `PrintStream` is used to write formatted data to the user's screen. `PrintStream` is the actual class used to perform the printing in methods, like this:

> `System.out.print()
> System.out.println()`

> It is possible to do autoflushing with `PrintStream`. The two constructors to use with `PrintStream` are

> `PrintStream(OutputStream)-Creates a new PrintStream
> PrintStream(OutputStream, boolean)-Creates a new PrintStream, with autoflushing`

> `PrintStream` formats primitive data types for display to the screen. The following methods are used:

> `print(Object)
> print(String)
> print(char[])
> print(char)
> print(int)
> print(long)
> print(float)
> print(double)
> print(boolean)
> println()
> println(Object)
> println(String)
> println(char[])
> println(char)
> println(int)
> println(long)
> println(float)
> println(double)
> println(boolean)`

See Listing 12.3 for an example of the use of `PrintStream`.

> Listing 12.3. An example of the use of `PrintStream`.

> `/* Notes:
> ` This class implements a generic write class that can write any arbitrary
> object type to a file. The constructor is used to open the file. The
> resulting output stream is used as the constructor for the PrintStream
> class. PrintStream is used because it can write arbitrary objects.
> PrintStreams implicitly use "toString" methods within objects to
> convert objects to strings.
> An arbitrary class called PhoneInfo is created simply for the purpose of
> demonstrating PrintStream's ability to write any type of object.
> The main example simply populates a PhoneInfo array and then uses the
> WriteObjToFile class to actually write the information to the file. The
> filename to write to is specified on the command line.
> Syntax:
> MyMain <dest file>
> */
> import java.io.*;
> public class MyMain {
> public static void main (String args[]) {
> int i;
> // declare WriteObjToFile object
> WriteObjToFile w;
> // create info to populate phone info database
> String[] s = {"Roy Rogers", "(111) 111-1111",
> "Jesse James", "(222) 222-2222",
> "Wyatt Earp", "(333) 333-3333"};
> // declare PhoneInfo array
> PhoneInfo[] p;
> // create PhoneInfo array
> p = new PhoneInfo[s.length/2];
> // loop through PhoneInfo array creating phoneinfo objects
> for (i=0; i<s.length; i+=2) {
> p[i/2] = new PhoneInfo(s[i],s[i+1]);
> }
> try {
> // create WriteObjToFile object
> w = new WriteObjToFile(args[0]);
> // loop through phone database passing objects to WriteObjToFile
> for (i=0; i<p.length; i++) {
> w.write(p[i]);
> }
> }
> // catch IO exceptions
> catch(IOException e) {
> System.err.println("ERROR: IO Exception");
> System.exit(2);
> }
> }
> }
> // declare PhoneInfo class
> class PhoneInfo {
> // declare information variables
> String name, phoneNum;
> // declare PhoneInfo constructor
> public PhoneInfo(String name, String phoneNum) {
> // initialize name based on constructor argument
> this.name = new String(name);
> // initialize phone number based on constructor argument
> this.phoneNum = new String(phoneNum);
> }
> // declare toString method for returning string representation of instance
> public String toString() {
> // return string
> return("Name: " + name + "\nPhone Number: " + phoneNum);
> }
> }
> // declare WriteObjToFile class
> class WriteObjToFile {
> // declare PrintStream object
> PrintStream ps;
> // declare constructor
> public WriteObjToFile(String filename) throws IOException {
> try {
> // create printstream using FileOutPutStream as the stream to write to
> ps = new PrintStream(new FileOutputStream(filename));
> }
> // handle file not found errors
> catch (FileNotFoundException e) {
> System.err.println("ERROR: File not found");
> System.err.println(" File = " + filename);
> System.exit(2);
> }
> }
> // declare method to write arbitrary objects
> public void write (Object o) {
> // write object to output stream
> ps.println(o);
> }
> `}`

#### The `ByteArrayOutputStream` Class

`ByteArrayOutputStream`, the counterpart of `ByteArrayInputStream`, is used to create an input stream from a buffer-that is, it pushes Java output into a buffer. The buffer grows as needed.

The flow of data to the output stream is controlled by two variables:

- `buf`-The buffer where data is stored
- `Count`-The number of bytes in the buffer

With `ByteArrayOutputStream`, you can use the `reset` method, which resets the output stream buffer so that the space of the buffer is not released and can be reused. There is no `mark` method to mark a specific place in the stream.

#### The `FileOutputStream` Class

`FileOutputStream`, the counterpart to `FileInputStream`, enables Java to write to files. The file and directory must be accessible to Java, which is a security issue.

Warning
Be sure to explicitly close the file output stream if there are to be subsequent accesses to it after the end of file has been reached. Otherwise, the file will not be properly terminated with an end of file marker and you will get errors.

The only methods available to `FileOutputStream` are the following:

> `close()`-Closes the stream
> `finalize()`-Closes the stream when garbage is collected
> `getFD()`-Returns the file descriptor associated with this stream
> `write(int)-`Writes a byte of data
> `write(byte[])`-Writes an array of bytes
> `write(byte[], int, int)`-Writes a subarray of bytes

#### The `PipedOutputStream` Class

`PipedOutputStream` supports moving data to and from threads that are piped together using the `PipeInputStream`. Because `PipedOutputStream` is connected to the `PipeInputStream`, the two must work together.

The methods associated with these classes are

> `close()`-Closes the stream
> `connect(PipedInputStream)`-Connects this output stream to a receiver
> `write(int)`-Writes a byte
> `write(byte[], int, int)`-Writes a subarray of bytes

### Miscellaneous I/O Classes

The `java.io` package includes two miscellaneous I/O classes for dealing with files: `File` and `RandomAccessFile`.

#### The `File` Class

The `File` class is used to represent a filename on a host system. It cannot read or write to the file, but it can get information about the file such as its name, path, and so on. It works as an abstract way of dealing with a platform-specific file.

#### The `RandomAccessFile` Class

`RandomAccessFile` implements both `DataInput` and `DataOutput` interfaces. It combines both input and output access to a file within the security confines of Java. The numerous methods associated with it read and write primitive data types, close the file, and locate the file. `RandomAccessFile` also allows `skip`.

## The `java.util` Package

The `java.util` package is sort of a catch-all for handy utilities. It contains the following classes:

> `BitSet
> Date
> Dictionary
> Hashtable
> Observable
> Properties
> Random
> Stack
> StringTokenizer
> Vector`

As you can see, this is certainly a mixed bag of classes. Read on for a description of each one. See the online documentation for details on all the methods associated with each class.

### The `Bitset` Class

The `Bitset` class creates a set of bits that can grow as needed. It has methods that can manipulate the bits in the set. Listing 12.4 is an example of how to use `Bitset`.

> Listing 12.4. An example using `Bitset`.

> `/* Notes:
> ` This class does 7 bit even parity generation and checking.
> */
> import java.util.*;
> public class MyMain {
> public static void main (String args[]) {
> Parity p; // declare parity object
> p = new Parity((byte)100); // create parity object
> p.genParity(); // generate parity bit
> if (p.chkParity()) // check for parity error
> System.out.println("no parity error");
> else
> System.out.println("parity error");
> }
> }
> class Parity { // declare class parity
> BitSet b; // declare bitset object
> public Parity(byte data) { // declare parity constructor
> int i;
> b = new BitSet(8); // create new bitset object length 8
> for (i=0; i<7; i++) { // copy input data bits to bitset
> if (((1 << i) & data) == 1) { // test if data bit is 1
> b.set(i); // set corresponding bitset bit
> }
> }
> }
> public void genParity() { // method to generate parity bit
> int i, cnt;
> cnt = 0;
> for (i=0; i<7; i++) { // loop through bitset counting data bits
> if (b.get(i)) {
> cnt++;
> }
> }
> if ((cnt % 2) == 0) // test if even or odd number data bits set
> b.clear(7); // even, clear parity bit
> else
> b.set(7); // odd, set parity bit
> }
> public boolean chkParity() { // method to check for parity errors
> int i, cnt, parityBit;
> cnt = 0;
> for (i=0; i<7; i++) { // loop through bitset counting data bits
> if (b.get(i)) {
> cnt++; // increment count of set data bits
> }
> }
> if (b.get(7)) // get setting of parity bit
> parityBit = 1; // parity bit set
> else
> parityBit = 0; // parity bit not set
> if (((cnt %2) ^ parityBit) == 0) // check if parity bit set correctly
> return(true); // no parity error detected
> return(false); // parity error detected
> }
> `}`

### The `Date` Class

`Date` provides methods for examining and manipulating date and time. Time in Java is measured in milliseconds since January 1, 1970. Java attempts to handle time from the system with which it is interacting. UTC is Coordinated Universal Time, which seems to be the worldwide standard.

Note
The `Date` class does not work as documented in the Java API. Although you should be able to work with dates since 1900, dates before January 1, 1970 are generally not usable.

See Table 12.1 for a list of methods to see the full scope of this class.

Table 12.1. Methods available for the `Date` class.

Method | Purpose
`UTC(int, int, int, int, int, int)` | Calculates a UTC value from YMDHMS
`after(Date)` | Checks whether this date comes after the specified date
`before(Date)` | Checks whether this date comes before the specified date
`equals(Object)` | Compares this object against the specified object
`getDate()` | Returns the day of the month
`getDay()` | Returns the day of the week
`getHours()` | Returns the hour
`getMinutes()` | Returns the minute
`getMonth()` | Returns the month
`getSeconds()` | Returns the second
`getTime()` | Returns the time in milliseconds since the epoch
`getTimezoneOffset()` | Returns the time zone offset in minutes for the current locale that is appropriate for this time
`getYear()` | Returns the year after 1900
`hashCode()` | Computes a number that is used when storing objects in hash tables.
`parse(String)` | Given a string representing a time, parses it and returns the time value
`setDate(int)` | Sets the date
`setHours(int)` | Sets the hours
`setMinutes(int)` | Sets the minutes
`setMonth(int)` | Sets the month
`setSeconds(int)` | Sets the seconds
`setTime(long)` | Sets the time
`setYear(int)` | Sets the year
`toGMTString()` | Converts a date to a `String` object using the Internet GMT conventions
`toLocaleString()` | Converts a date to a `String` object, using the locale conventions
`toString()` | Converts a date to a `String` object using the UNIX time conventions

It is important to remember that months start with 0, which is January, and end with 11, which is December. The days of the week also start with 0, which is Sunday, and go through 6, which is Saturday. Dates of the month are normal.

Note
Dates that are not within the normal range parameters are interpreted through consecutive iterations of the date range. For example, 32 January is recognized as 1 February.

Listing 12.5 is an example of the use of the `Date` class.

> Listing 12.5. Using `Date`.

> `/* Notes:
> ` Java's time handling utilities in java.util do not seem to handle
> dates before 1970 even though it is documented as 1900.
> Usage: date specified on the command line as first argument:
> MyMain "18 Apr 1972"
> */
> import java.util.*;
> public class MyMain {
> public static void main (String args[]) {
> BDay b; // declare birthday object;
> b = new BDay(args[0]); // create birthday object initialized
> // to first date specified on command line
> b.printBDayInfo(); // print out resulting birthday information
> }
> }
> class BDay { // declare new class birthday
> String sign; // declare string object to hold Astrological sign
> Date d;
> // declare date object to hold date of birth
> public BDay(String date) { // declare constructor for this class
> Date c; // declare date object used for comparisons
> int year; // declare int to hold year of birth
> d = new Date(date);
> // create new date object initialized to birthday
> year = d.getYear(); // get year from birth date
> while (true) { // loop finding Astrological sign
> c = new Date("20 Jan " + year);
> // create comparison date of end of capricorn period
> if (d.before(c)) {
> // check if birth date came before capricorn
> sign = new String("Capricorn"); // if so, set sign to capricorn
> break; &nbs p;// break out of while loop
> }
> c = new Date("19 Feb " + year); // repeat above for aquarius
> if (d.before(c)) {
> sign = new String("Aquarius");
> break;
> }
> c = new Date("21 Mar " + year); // repeat above for pisces
> if (d.before(c)) {
> sign = new String("Pisces");
> break;
> }
> c = new Date("20 Apr " + year); // repeat above for aries
> if (d.before(c)) {
> sign = new String("Aries");
> break;
> }
> c = new Date("21 May " + year); // repeat above for taurus
> if (d.before(c)) {
> sign = new String("Taurus");
> break;
> }
> c = new Date("21 Jun " + year); // repeat above for gemini
> if (d.before(c)) {
> sign = new String("Gemini");
> break;
> }
> c = new Date("23 Jul " + year); // repeat above for cancer
> if (d.before(c)) {
> sign = new String("Cancer");
> break;
> }
> c = new Date("23 Aug " + year); // repeat above for leo
> if (d.before(c)) {
> sign = new String("Leo");
> break;
> }
> c = new Date("23 Sep" + year); // repeat above for virgo
> if (d.before(c)) {
> sign = new String("Virgo");
> break;
> }
> c = new Date("23 Oct " + year); // repeat above for libra
> if (d.before(c)) {
> sign = new String("Libra");
> break;
> }
> c = new Date("22 Nov " + year); // repeat above for scorpio
> if (d.before(c)) {
> sign = new String("Scorpio");
> break;
> }
> c = new Date("22 Dec" + year); // repeat above for sagittarius
> if (d.before(c)) {
> sign = new String("Sagittarius");
> break;
> }
> c = new Date("31 Dec" + year); // catch end case for capricorn
> if (d.before(c)) {
> sign = new String("Capricorn");
> break;
> }
> }
> }
> // declare method for printing birthdate information
> public void printBDayInfo() {
> Date t,c;
> // declare date objects for todays date and for comparisons
> t = new Date(); // obtain todays date
> t.setHours(0);
> // set hours of todays date to zero
> t.setMinutes(0);
> // set minutes of todays date to zero
> t.setSeconds(0);
> // set seconds of todays date to zero
> c = new Date(t.getYear(), (d.getMonth()-1), d.getDate());
> // create date object for this years birthday
> System.out.println("You were born on: " + (d.getMonth()+1) + "/" +
> d.getDate() + "/" + d.getYear()); // print out birth date
> System.out.println("Your sign is: " + sign);
> // print out Astrological sign
> if (c.before(t))
> // check if birthday already occurred this year
> System.out.println("Your birthday has already occurred this year");
> // print out birthday already occurred
> else
> if (c.after(t))
> // check if birthday is yet to come this year
> System.out.println("Your birthday has yet to occur this year");
> // print out birthday is yet to come
> else
> System.out.println("TODAY IS YOUR BIRTHDAY!");
> // if neither before today or after today, it must be today
> }
> `}`

As you can see, there are numerous ways to use `Date`'s methods to manipulate and examine dates.

### The `Dictionary` Class

`Dictionary` is an abstract class. Its only current subclass is `Hashtable`. `Dictionary` is used to create a way of organizing objects. (See the following "`Hashtable`" section for the implementation of `Dictionary`.)

The idea is to access objects nonsequentially. There are keys to identify and access objects. Think of `Dictionary` as storing objects in a structure similar to an indexed file.

### The `Hashtable` Class

`Hashtable` extends `Dictionary` and is used to map keys to values. The methods associated with `Hashtable` enable the placing, locating, and retrieving of objects that are used as keys. The `Properties` class extends `Hashtable`.

### The `Properties` Class

`Properties` is a class that loads an input stream into a hash table. It also allows saves and gets from the hash table.

### The `Random` Class

`Random` contains methods that create pseudo-random numbers. These numbers can be either `Gaussian`, `Double`, `Float`, `Int`, or `Long`. The seed, or starting point, can be reset anytime using the appropriate method.

### The `Vector` Class

`Vector` is the abstract parent class for `Stack`. You will use the vector class to implement a growable array of objects.

### The `Stack` Class

`Stack` extends the `Vector` class. It creates a last in, first out (LIFO) stack of objects. See Listing 12.6 for an example using `Stack`.

> Listing 12.6. An example using `Stack`.

> `/* Notes:
> ` Either java or NT java will not accept "-" as a command line argument.
> The user must specify "--" to get the program to simply see "-".
> This program works by specifying an RPN string on the command line.
> */
> import java.util.*;
> public class MyMain {
> public static void main (String args[]) {
> // declare RPN calculator object
> RPncalculator c;
> // create RPN calculator passing command line arguments
> c = new RPncalculator(args);
> }
> }
> // declare new RPN calculator class
> class RPncalculator {
> // declare Stack object
> Stack s;
> // declare generic object
> Object o;
> // RPN Calculator constructor which also solves equation string passed to it
> public RPncalculator(String args[]) {
> int i,j;
> int[] num;
> // declare object to hold current arithmetic operator
> Character operator;
> // create new stack
> s = new Stack();
> // create two integer array to hold operands
> num = new int[2];
> // loop through equation strings
> for (i=0; i < args.length; i++) {
> // handle number format exceptions
> try {
> // try converting string to number and push on stack if successful
> s.push(new Integer(args[i]));
> }
> // string is not a number, must be an operator
> catch(java.lang.NumberFormatException e) {
> // convert string operator to character
> operator = new Character(args[i].charAt(0));
> // loop through operands operator will be used with
> for (j=0; j<2; j++) {
> // not enough operands on stack, generate error
> if (s.empty()) {
> System.err.println("ERROR: stack is empty");
> System.exit(2);
> }
> // extract operand from stack
> num[j] = ((Integer)s.pop()).intValue();
> }
> // switch based on operator
> switch (operator.charValue()) {
> // operator is "+", add operands
> case '+':
> s.push(new Integer(num[1] + num[0]));
> break;
> // operator is "-", subtract operands
> case '-':
> s.push(new Integer(num[1] - num[0]));
> break;
> // operator is "*", multiply operands
> case '*':
> s.push(new Integer(num[1] * num[0]));
> break;
> // operator is "/", divide operands
> case '/':
> s.push(new Integer(num[1] / num[0]));
> break;
> default:
> // unknown operator, print error message
> System.err.println("ERROR: invalid operator: " + operator);
> System.exit(3);
> break;
> }
> }
> }
> // value remaining on stack must be answer, print to screen
> System.out.println(((Integer)s.pop()).intValue());
> }
> `}`

### The `StringTokenizer` Class

The `StringTokenizer` class provides a set of methods for converting an input stream into a set of tokens. Methods are provided for specifying which characters make up a token, which characters serve as token delimiters, whether case should be considered, and whether numeric characters should be converted to numbers. The `StringTokenizer` class also understands the `/* */` comment-naming conventions of C, C++, and Java as well as the `//` used in C++ and Java.

The `StringTokenizer` class specifies all the parts that determine a token and then retrieves a single token in its entirety piece by piece from an input stream. This can be used for anything from splitting a simple sentence into individual words to processing something as complex as Java source code. (See the online documentation for details of the individual methods.)

## Summary

Java provides several ways to deal with moving data through its applications. The `java.io` package contains classes that handle the input and output of data. The data arrives in a stream and can be sliced and diced in various ways by the subclasses of the abstract classes `InputStream` and `OutputStream`.

The data stream may block, or wait, if the flow is not continuous. Both input and output classes provide buffers to smooth this flow. All input classes are able to skip a certain number of bytes forward in the stream; some classes can mark a spot and then reset the stream to that spot. Some classes store the data in byte arrays, and one class stores it in a character string array.

Data accessed or stored by Java must originate or be placed in an area that is Java accessible. Much of the Java security schema relies on the segmentation of Java data from other system data. Therefore, it would not be a good idea to put a copy of your password file in this area.

The `java.io` package doesn't care where data originates; it only cares about what the programmer wants to do with it. The data-manipulation classes enable Java to be truly non-platform-specific, even when manipulating data.

The `java.util` package contains classes that add functionality to Java. These classes include a date manipulator (`Date`) and a bitset creator and manipulator (`Bitset`). There are also classes that provide a mechanism for a hash table structure of an object file (`Dictionary` and `Hashtable`). There is a pseudo-random number generator (`Random`). Another class creates a stack of objects (`Stack`), and another turns a string of characters into tokens (`StringTokenizer`).