Question:
How do I read a series of integers from an ASCII text file? The file contains a sequence of numbers like
110 120 130 140 ...
I tried to use readInt()
andDataInputStream
, but all it returned were some random values.
Answer: DataInputStream
is designed to read the binary representation of intrinsic Java types from an input stream. The readInt
method reads 4 bytes and interprets them as a big endian two’s complement integer. You wound upwith apparently random values because the integers you were trying to read were stored as ASCII text.
The only way to read numbers stored in an ASCII text file is to read them as strings and then convert them to Java integers. One approach is toread the input line by line, tokenize the input yourself, and use Integer.parseInt
to convert the strings to Java integers. This requires that you write quite a bit of extra code.
A second approach is to use the StreamTokenizer
class, which already does most of the work for you. A StreamTokenizer
will read whitespace separated tokens from an InputStream
or reader and optionally parse numerical input for you. The class is not elegantly designed, but gets the job done for this common case. Eachtoken is read sequentially from the stream by calling nextToken()
, which returns the type code of the token. A type code of StreamTokenizer.TT_EOF
indicates that the end of the input has been reached. Youcan tell the class to parse numbers for you by calling parseNumbers()
. Number tokens are identified by the TT_NUMBER
constant and are retrieved by reading the public variable nval
.Number parsing is generalized to include both integers and floating point, so the nval
variable is of typedouble
. String tokens are stored in sval
. This ad hoc method of accessing token values is why I called the classinelegant, but it works.
The following code listing demonstrates how to use the StreamTokenizer
class. It reads a series of numbers from a file, adds them up, and prints out the total. I also provide sample input for you to test the program.
import java.io.*;/*** * This program reads a list of whitespace separated numbers from * a text file, adds them up, and prints the total. It demonstrates * how to use the StreamTokenizer class. You can use the sample * ReadNumbers.txt file as input. ***/public class ReadNumbers { public static void main(String[] args) { int tokenType; FileReader input; StreamTokenizer tokenizer; double total; if(args.length != 1) { System.err.println("Usage: ReadNumbers"); return; } try { input = new FileReader(args[0]); } catch(FileNotFoundException e) { System.err.println("File not found."); return; } tokenizer = new StreamTokenizer(input); // Tell the tokenizer to parse numbers for us tokenizer.parseNumbers(); total = 0.0; try { while((tokenType = tokenizer.nextToken()) != StreamTokenizer.TT_EOF) { if(tokenType != StreamTokenizer.TT_NUMBER) { System.err.println("Invalid input file! Only expecting numbers."); return; } total+=tokenizer.nval; } } catch(IOException e) { System.err.println("Error reading next token."); return; } System.out.println("Total: " + total); } }
10.12 20.0 30 40 91 22.5213 56 78.42 92.88 17.001