Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 6
The DataInputStream class, on the other hand, takes a different approach when reporting end of file:
// In source packet in file except/ex9b/Example9b.java
import java.io.*;
class Example9b {
public static void main(String[] args)
throws IOException {
if (args.length == 0) {
System.out.println("Must give filename as first arg.");
return;
}
FileInputStream fin;
try {
fin = new FileInputStream(args[0]);
}
catch (FileNotFoundException e) {
System.out.println("Can't find file: " + args[0]);
return;
}
DataInputStream din = new DataInputStream(fin);
try {
int i;
for (;;) {
i = din.readInt();
System.out.println(i);
}
}
catch (EOFException e) {
}
fin.close();
}
}
Each time the readInt() method of DataInputStream is invoked, it reads four bytes from the stream and interprets them as an int. When readInt() encounters end of file, it throws EOFException.
Throwing an exception is a reasonable approach for this method for two reasons. First, readInt() can't return a special value to indicate end of file, because all possible return values are valid ints. (It can't return -1 on end of file, for example, because it may read a -1 from the stream and need to return it as a valid
int value.) Second, if readInt() encounters end of file after reading only one, two, or three bytes, that probably qualifies as an "abnormal condition." The
method is supposed to read four bytes, but only one to three are available. Given that this exception is an integral part
of using this class, it is a checked exception (a subclass of Exception). Client programmers are forced to deal with it.
A third approach to signaling an "end has been reached" condition is illustrated by the StringTokenizer and Stack classes in the following example:
// In source packet in file except/ex9b/Example9c.java
// This program prints the white-space separated tokens of an
// ASCII file in reverse order of their appearance in the file.
import java.io.*;
import java.util.*;
class Example9c {
public static void main(String[] args)
throws IOException {
if (args.length == 0) {
System.out.println("Must give filename as first arg.");
return;
}
FileInputStream in = null;
try {
in = new FileInputStream(args[0]);
}
catch (FileNotFoundException e) {
System.out.println("Can't find file: " + args[0]);
return;
}
// Read file into a StringBuffer
StringBuffer buf = new StringBuffer();
try {
int ch;
while ((ch = in.read()) != -1) {
buf.append((char) ch);
}
}
finally {
in.close();
}
// Separate StringBuffer into tokens and
// push each token into a Stack
StringTokenizer tok = new StringTokenizer(buf.toString());
Stack stack = new Stack();
while (tok.hasMoreTokens()) {
stack.push(tok.nextToken());
}
// Print out tokens in reverse order.
while (!stack.empty()) {
System.out.println((String) stack.pop());
}
}
}
This example reads in the bytes of a file, converts them to chars, and places the chars into a StringBuffer. It then uses a StringTokenizer to extract one white-space separated token (a String) at a time and push it onto a Stack. Next it pops all tokens from the Stack and prints them out one per line. Because Stack implements a Last In First Out (LIFO) stack, the tokens are printed in reverse order from their appearance in the file.