|
|
See also: http://www.cs.rit.edu/usr/local/jdk/docs/api/java/io/package-summary.html
File:
In Java, file I/O as well as keyboard/screen I/O is handled by streams.
InputStreamReader and OutputStreamWriter combine an encoding and a stream and thus are the preferred classes for text input and output. This means they are byte based.
Reader and Writer classes are abstract -- they can have abstract methods (declaration without a body) and no objects may be instantiated. Abstract classes define basic behavior for related subclasses including instance variables and some method implementations.
Text files normally contain byte values that represent a selection of char values by way of an encoding like 8859_1 (ISO Latin-1), or a code page like Cp850 (PC Latin-1), or with the unicode transfer format UTF8.
For an input stream, the source of data might be a file, a String, an array of bytes, or bytes written to an output stream (typically by another thread). There are also "filter input streams" that take data from another input stream and transform or augment the data before delivering it as input. For example, a DataNumberInputStream passes bytes through verbatim but counts line terminators as they are read.
The drawings have been created by Charles L. Perkins.
For an output stream, the sink of data might be a file, an array of bytes, or a buffer to be read as an input stream (typically by another thread). There are also "filter output streams" that transform or augment data before writing it to some other output stream.
An instance of class File represents a path name (a String) that might identify a particular file within a file system. Certain operations on the file system, such as renaming and deleting files, are done by this class rather than through streams.
No matter where the information is coming from or going to the algorithm for reading/writing is pretty much always the same:
Reading:
open a stream for reading
while more information
read
process
close stream
Writing:
open a stream for writing
while more information
process
write
close stream
An instance of class FileDescriptor represents an abstract indication of a particular file within a file system; such file descriptors are created internally by the Java I/O system.
Methods:
The Solaris man page:
sync() causes all information in memory that should be on disk to be written out. This includes modified super blocks, modified i-nodes, and delayed block I/O.
It should be used by programs that examine a file system, such as fsck.1m df.1m etc. It is mandatory before a re-boot.
The writing, although scheduled, is not necessarily completed before sync() returns. The fsync function completes the writing before it returns.
Processing streams perform some sort of operation, such as buffering or character encoding, as they read and write. Like the data sink streams, java/io often contains pairs of streams: one that performs a particular operation during reading and another that performs the same operation (or reverses it) during writing. This table gives java/io's processing streams
---------------------+--------------------+-----------------------
Process | Character Stream | Byte Stream
---------------------+--------------------+-----------------------
Buffering | BufferedReader, | BufferedInputStream,
| BufferedWriter | BufferedOutputStream
---------------------+--------------------+-----------------------
Filtering | FilterReader, | FilterInputStream,
| FilterWriter | FilterOutputStream
Converting between | InputStreamReader, |
Bytes and Characters | OutputStreamWriter |
---------------------+--------------------+-----------------------
Concatenation | | SequenceInputStream
---------------------+--------------------+-----------------------
Object Serialization | | ObjectInputStream,
| | ObjectOutputStream
---------------------+--------------------+-----------------------
Data Conversion | | DataInputStream,
| | DataOutputStream
---------------------+--------------------+-----------------------
Counting | LineNumberReader | LineNumberInputStream
---------------------+--------------------+-----------------------
Peeking Ahead | PushbackReader | PushbackInputStream
---------------------+--------------------+-----------------------
Printing | PrintWriter | PrintStream
---------------------+--------------------+-----------------------
Data sink streams read from or write to specialized data sinks such as strings, files, or pipes. Typically, for each reader or input stream intended to read from a specific kind of input source, java/io contains a parallel writer or output stream that can create it. The following table gives java/io's data sink streams.
Sink Type Character Streams Byte Streams
Memory CharArrayReader, ByteArrayInputStream,
CharArrayWriter ByteArrayOutputStream
StringReader, StringBufferInputStream
StringWriter StringBufferInputStream
Pipe PipedReader, PipedInputStream,
PipedWriter PipedOutputStream
File FileReader, FileInputStream,
FileWriter FileOutputStream
CharArrayReader and CharArrayWriter
Use these streams to read from and write to memory. You create these streams on an existing array and then use the read and write methods to read from or write to the array.
FileReader and FileWriter
FileInputStream and FileOutputStream
Collectively called file streams, these streams are used to read from or write to a file on the native file system.
PipedReader and PipedWriter
PipedInputStream and PipedOutputStream
Implement the input and output components of a pipe. Pipes are used to channel the output from one program (or thread) into the input of another.
StringReader and StringWriter
StringBufferInputStream
Use StringReader to read characters from a String as it lives in memory. Use StringWriter to write to a String. StringWriter collects the characters written to it in a StringBuffer, which can then be converted to a String. StringBufferInputStream is similar to StringReader, except that it reads bytes from a StringBuffer.
The class StreamTokenizer provides some simple support for parsing bytes or characters from an input stream into tokens such as identifiers, numbers, and strings, optionally ignoring comments and optionally recognizing or ignoring line terminators.
The hierarchy of classes defined in package http://www.cs.rit.edu/usr/local/jdk/docs/api/java/io/package-summary.html
import java.io.*;
public class InOut_1 {
public static void main( String args[] ) {
DataInputStream in;
DataOutputStream out;
byte[] buffer = new byte[1024];
int n;
if ( args.length < 2 ) {
System.err.println(
"Usage: java InOut_1 from to");
System.exit(1);
}
try {
in = new DataInputStream(
new FileInputStream(args[0]) );
out = new DataOutputStream(
new FileOutputStream(args[1]) );
while ( (n = in.read(buffer) ) != -1 ) {
out.write(buffer, 0, n);
}
out.close();
in.close();
}
catch ( FileNotFoundException ef) {
System.out.println("File not found: " + args[1]);
}
catch ( IOException ef) {
System.out.println("File not found: " + args[1]);
}
catch ( Exception e) {
System.out.println("ExceptionType occurred: " +
e.getMessage() );
}
}
}
Source Code: Src/9_was/InOut_1.java
Result:
% java InOut_1 % java InOut_1 InOut_2.class x % diff InOut_1.class x %
Does the size of the read and write blocks matter?
import java.io.*;
public class InOut_2 {
static final int BUFSIZE = 1024;
public static void copy( String inF , String outF, int bufSize ) {
DataInputStream in;
DataOutputStream out;
byte[] buffer = new byte[bufSize];
int n;
try {
in = new DataInputStream(
new FileInputStream(inF) );
out = new DataOutputStream(
new FileOutputStream(outF) );
while ( (n = in.read(buffer) ) != -1 ) {
out.write(buffer, 0, n);
}
out.close();
in.close();
}
catch ( FileNotFoundException ef) {
System.out.println(ef.getMessage() );
}
catch ( IOException ef) {
System.out.println(ef.getMessage() );
}
catch ( Exception e) {
System.out.println("ExceptionType occurred: " +
e.getMessage() );
}
}
public static void main( String args[] ) {
int bufSize = BUFSIZE;
if ( args.length < 2 ) {
System.err.println(
"Usage: java InOut_1 from to [size]");
System.exit(1);
}
if ( args.length == 3 ) {
try {
bufSize = Integer.parseInt(args[2]);
}
catch ( NumberFormatException e ) {
System.out.println("Can't convert " + args[2]
+ " to an integer.");
}
}
System.out.println("BufferSize = " + bufSize);
copy(args[0], args[1], bufSize);
}
}
Source Code: Src/9_was/InOut_2.java
Result:
% for i in 1 2 512 1024 10240 > do > /usr/bin/time java InOut_2 from to $i && diff from to > done BufferSize = 1 real 49.8 user 21.3 sys 24.4 BufferSize = 2 real 27.0 user 10.8 sys 12.3 BufferSize = 512 real 0.8 user 0.2 sys 0.2 BufferSize = 1024 real 0.8 user 0.1 sys 0.2 BufferSize = 10240 real 1.0 user 0.2 sys 0.1
import java.io.*;
public class stdin {
public static void main( String args[] ) {
LineNumberInputStream input;
if ( args.length > 1 ) {
System.err.println(
"Usage: java stdin file-name");
System.exit(1);
}
try {
String line;
//
if ( args.length == 1 )
input = new LineNumberInputStream(
new DataInputStream(
new FileInputStream(args[0]) ) );
else
input = new LineNumberInputStream( System.in );
while ( ( input.read() ) != -1 ) {
;
}
System.out.println("# lines = " + input.getLineNumber() );
input.close();
}
catch ( FileNotFoundException e) {
System.out.println(e.getMessage());
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( Exception e) {
System.out.println("ExceptionType occurred: " +
e.getMessage() );
}
}
}
Source Code: Src/14/stdin.java
/**
* Opens the file with the data.
* A rewind will happen, if this method gets called more than once.
**/
public void openFileForReading() {
try {
if ( isBinaryInput ) {
bInputStream = new DataInputStream(
new GZIPInputStream(
new FileInputStream(inputFileName)
)
);
} else {
inputStream = new BufferedReader(new FileReader(inputFileName));
}
...
} catch ( Exception e ) {
e.printStackTrace();
InOutErr.out.println("ParticleViewExtractor: -openFileForReading- " + e);
}
}
/*
* Convert Data to Binary format
*/
public void doConvertToBinary(String fileName) {
try {
BufferedReader inputStream = new BufferedReader(new FileReader(fileName));
DataOutputStream outputStream = new DataOutputStream(
new GZIPOutputStream(
new FileOutputStream(fileName + ".binary.Z")
)
... );
}
Source Code: Src/14/Compressed.java
Extract from:
http://www.cs.rit.edu/usr/local/jdk/docs/api/java/io/BufferedReader.html
BufferedReader(Reader)
Create a buffering character-input
stream that uses a default-sized input buffer.
BufferedReader(Reader, int)
Create a buffering character-input
stream that uses an input buffer of the specified
size.
import java.io.*;
public class Grep {
public static void main( String args[] ) {
BufferedReader input;
PrintWriter output;
if ( args.length < 2 ) {
System.err.println(
"Usage: java Grep search-string file-name [outputfilename]");
System.exit(1);
}
try {
String line;
input = new BufferedReader(
new FileReader(args[1])
);
if ( args.length == 3 ) {
output = new PrintWriter( new FileWriter(args[2]) );
} else
output = new PrintWriter(System.out);
while ( ( line = input.readLine() ) != null ) {
if ( line.indexOf(args[0]) >= 0 )
output.println(line);
}
output.close();
input.close();
}
catch ( FileNotFoundException e) {
System.out.println(e.getMessage());
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( Exception e) {
System.out.println("ExceptionType occurred: " +
e.getMessage() );
}
}
}
Source Code: Src/9_was/Grep.java
% java Grep Grep Grep.java
public class Grep {
"Usage: java Grep search-string file-name [outputfilename]");
% java Grep Grep
Usage: java Grep search-string file-name [outputfilename]
If you are interessted in line numbers, choose LineNumberReader
import java.io.*;
public class Grep2 {
public static void main( String args[] ) {
LineNumberReader input;
PrintWriter output;
if ( args.length < 2 ) {
System.err.println(
"Usage: java Grep search-string file-name [outputfilename]");
System.exit(1);
}
try {
String line;
input = new LineNumberReader (
new BufferedReader(
new FileReader(args[1])
)
);
if ( args.length == 3 ) {
output = new PrintWriter( new FileWriter(args[2]) );
} else
output = new PrintWriter(System.out);
while ( ( line = input.readLine() ) != null ) {
if ( line.indexOf(args[0]) >= 0 )
output.println(input.getLineNumber() +
": " + line);
}
output.close();
input.close();
}
catch ( FileNotFoundException e) {
System.out.println(e.getMessage());
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( Exception e) {
System.out.println("ExceptionType occurred: " +
e.getMessage() );
}
}
}
Source Code: Src/9_was/Grep2.java
% java Grep2 Grep Grep.java
3: public class Grep {
10: "Usage: java Grep search-string file-name [outputfilename]");
%
See also here: Pattern
/*
* Checks for invalid characters
* in email addresses
*/
import java.util.regex.*;
public class EmailValidation {
/*
* Checks for email addresses starting with
* inappropriate symbols like dots or @ signs.
*/
public static void checkForPorA(String aPossibleEmail ) {
Pattern p = Pattern.compile("^\\.|^\\@");
Matcher m = p.matcher(aPossibleEmail);
if (m.find())
System.err.println(aPossibleEmail + " - Email addresses don't start" +
" with dots or @ signs.");
else
System.err.println(aPossibleEmail + " is valid.");
}
/*
* Checks for email addresses starting with
* www.
*/
public static void checkForWWW(String aPossibleEmail ) {
Pattern p = Pattern.compile("^www\\.");
Matcher m = p.matcher(aPossibleEmail);
if (m.find())
System.err.println(aPossibleEmail + " - Email addresses don't start" +
" with www.");
else
System.err.println(aPossibleEmail + " is valid.");
}
/*
* Checks for invalid characters in email addresses.
*/
public static void checkForInvalidC(String aPossibleEmail ) {
Pattern p = Pattern.compile("[^A-Za-z0-9\\.\\@_\\-~#]+");
Matcher m = p.matcher(aPossibleEmail);
StringBuffer sb = new StringBuffer();
boolean result = m.find();
boolean deletedIllegalChars = false;
while(result) {
deletedIllegalChars = true;
m.appendReplacement(sb, "");
result = m.find();
}
if (deletedIllegalChars) {
System.out.println("It contained incorrect characters" +
" , such as spaces or commas.");
}
}
public static void main(String[] args) throws Exception {
checkForPorA("hpb@cs.rit.edu");
checkForPorA("@cs.rit.edu");
checkForWWW("www.cs.rit.edu");
checkForInvalidC("hpb@cs.rit.edu");
checkForInvalidC("p b@cs.rit.edu");
}
}
Source Code: Src/9_reg_ex/EmailValidation.java
/*
* Checks for invalid characters
* in email addresses
*/
import java.util.regex.*;
public class TheN {
/*
* Palindroms
*/
public static void checkForP(String aPossibleEmail ) {
Pattern p = Pattern.compile("^.$");
Matcher m = p.matcher(aPossibleEmail);
if (m.find())
System.err.println(aPossibleEmail + " one character");
else
System.err.println(aPossibleEmail + " more than one character");
}
public static void checkForP2(String aPossibleEmail ) {
Pattern p = Pattern.compile("^(.).\\1$");
Matcher m = p.matcher(aPossibleEmail);
if (m.find())
System.err.println(aPossibleEmail + " 2 char palindrom");
else
System.err.println(aPossibleEmail + " ! a 2 char palindrom");
}
public static void main(String[] args) throws Exception {
checkForP("a");
checkForP("aa");
checkForP2("a");
checkForP2("ata");
if ( Pattern.matches("^(.)\\1$", "aa" ))
System.err.println("palindrom");
}
}
Source Code: Src/9_reg_ex/TheN.java
Object writer:
import java.io.*;
import java.util.Date;
public class ObjectWriter_1 {
public static void main( String args[] ) {
Date d = new Date();
try {
FileOutputStream ostream =
new FileOutputStream("object_1.data");
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeInt(12345);
System.out.println("Integer = " + 1234);
p.writeObject("Today");
System.out.println("String = " + "Today");
p.writeObject(d);
System.out.println("Date = " + d);
p.flush();
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
}
}
Source Code: Src/9_was/ObjectWriter_1.java
% java ObjectWriter_1 Integer = 1234 String = Today Date = Tue Oct 15 15:28:59 EDT 2002
Object Reader:
import java.io.*;
import java.util.Date;
public class ObjectReader_1 {
public static void main( String args[] ) {
try {
FileInputStream istream =
new FileInputStream("object_1.data");
ObjectInputStream p = new ObjectInputStream(istream);
int i = p.readInt();
System.out.println("Integer = " + i);
String today = (String)p.readObject();
System.out.println("String = " + today);
Date date = (Date)p.readObject();
System.out.println("Date = " + date);
p.close();
istream.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
Source Code: Src/9_was/ObjectReader_1.java
% java ObjectReader_1 Integer = 1234 String = Today Date = Tue Oct 15 15:29:07 EDT 2002
ls -l o*a -rw------- 1 hpb fac 60 Oct 4 10:49 object_1.data yps 9 85 od -c object_1.data 0000000 254 355 \0 005 w 004 \0 \0 0 9 t \0 005 T o d 0000020 a y s r \0 016 j a v a . u t i l . 0000040 D a t e h j 201 001 K Y t 031 003 \0 \0 x 0000060 p w \b \0 \0 \0 326 365 < o 232 x 0000074
When an object is serialized, any object reference it contains are also serialized. A HashTable example.
import java.io.*;
import java.util.*;
public class ObjectWriter_2 {
public static void main( String args[] ) {
Hashtable aHashTable = new Hashtable();
aHashTable.put("plus Movie", "A little Voice");
aHashTable.put("minus Movie", "Independence Day");
try {
FileOutputStream ostream =
new FileOutputStream("object_2.data");
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(aHashTable);
System.out.println("aHashTable = " + aHashTable.toString());
p.flush();
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
}
}
Source Code: Src/9_was/ObjectWriter_2.java
% java ObjectWriter_2
aHashTable = {minus Movie=Independence Day, plus Movie=A little Voice}
import java.io.*;
import java.util.*;
public class ObjectReader_2 {
public static void main( String args[] ) {
Hashtable aHashTable;
try {
FileInputStream istream =
new FileInputStream("object_2.data");
ObjectInputStream p = new ObjectInputStream(istream);
aHashTable= (Hashtable)p.readObject();
System.out.println("aHashTable = " + aHashTable.toString());
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
Source Code: Src/9_was/ObjectReader_2.java
% java ObjectReader_2
aHashTable = {minus Movie=Independence Day, plus Movie=A little Voice}
import java.io.*;
import java.util.*;
public class Self {
public static void main( String args[] ) {
Hashtable aHashTable = new Hashtable();
aHashTable.put("plus Movie", "A little Voice");
aHashTable.put("The HashTable", aHashTable);
try {
FileOutputStream ostream =
new FileOutputStream("self.data");
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(aHashTable);
p.flush();
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
}
Source Code: Src/9_was/Self.java
% java Self % od -c self.data 0000000 254 355 \0 005 s r \0 023 j a v a . u t i 0000020 l . H a s h t a b l e 023 273 017 % ! 0000040 J 344 270 003 \0 002 F \0 \n l o a d F a c ... 0000160 M o v i e t \0 016 A l i t t l 0000200 e V o i c e x 0000210
import java.io.*;
import java.util.*;
public class Self_Reader {
public static void main( String args[] ) {
Hashtable aHashTable;
try {
FileInputStream istream =
new FileInputStream("self.data");
ObjectInputStream p = new ObjectInputStream(istream);
aHashTable= (Hashtable)p.readObject();
System.out.println("plus Movie = " + aHashTable.get("plus Movie"));
System.out.println("The HashTable" + aHashTable.get("The HashTable"));
System.out.println("aHashTable = " + aHashTable.toString());
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
Source Code: Src/9_was/Self_Reader.java
% java Self_Reader 2>&1 | more // version jdk1.3.1
plus Movie = A little Voice
java/lang/StackOverflowError
at java/lang/StringBuffer.<init>(StringBuffer.java)
at java/gutil.Hashtable.toString(Hashtable.java)
at java/gutil.Hashtable.toString(Hashtable.java)
...
% java Self_Reader // version jdk1.4
plus Movie = A little Voice
The HashTable{The HashTable=(this Map), plus Movie=A little Voice}
aHashTable = {The HashTable=(this Map), plus Movie=A little Voice}
The first shot is using a 'Serializable' class:
import java.io.*;
import java.util.*;
public class ObjectWriter_3 extends Hashtable {
int local = 42;
public static void main( String args[] ) {
ObjectWriter_3 aObjectWriter_3 = new ObjectWriter_3();
try {
FileOutputStream ostream =
new FileOutputStream("object_3.data");
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(aObjectWriter_3);
System.out.println("aObjectWriter_3 = " + aObjectWriter_3.toString());
System.out.println("aObjectWriter_3.local = " + aObjectWriter_3.local);
p.flush();
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/9_was/ObjectWriter_3.java
% java ObjectWriter_3
aObjectWriter_3 = {}
aObjectWriter_3.local = 42
import java.io.*;
import java.util.*;
public class ObjectReader_3 {
public static void main( String args[] ) {
ObjectWriter_3 aObjectWriter_3;
try {
FileInputStream istream =
new FileInputStream("object_3.data");
ObjectInputStream p = new ObjectInputStream(istream);
aObjectWriter_3= (ObjectWriter_3)p.readObject();
System.out.println("ObjectWriter_3.local = " + aObjectWriter_3.local);
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
catch ( ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/9_was/ObjectReader_3.java
% java ObjectReader aObjectWriter_3.local = 42
import java.io.*;
import java.util.*;
public class ObjectWriter_4 implements Serializable {
int local = 42;
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
// customized serialization code
}
private void readObject(ObjectInputStream s) throws IOException {
try {
s.defaultReadObject();
}
catch ( ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
// customized deserialization code
// ...
// followed by code to update the object, if necessary
}
public static void main( String args[] ) {
ObjectWriter_4 aObjectWriter_4 = new ObjectWriter_4();
try {
FileOutputStream ostream =
new FileOutputStream("object_4.data");
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeObject(aObjectWriter_4);
System.out.println("aObjectWriter_4 = " + aObjectWriter_4.toString());
System.out.println("aObjectWriter_4.local = " + aObjectWriter_4.local);
p.flush();
p.close();
}
catch ( IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/9_was/ObjectWriter_4.java
% java ObjectWriter_4 aObjectWriter_4 = ObjectWriter_4@1dc60810 aObjectWriter_4.local = 42
The reader program must not be modified.
The StreamTokenizer class takes an input stream and parses it into "tokens", allowing the tokens to be read one at a time. The parsing process is controlled by a table and a number of flags that can be set to various states. The stream tokenizer can recognize identifiers, numbers, quoted strings, and various comment styles.
Each byte read from the input stream is regarded as a character in the range '\u0000' through '\u00FF'. The character value is used to look up five possible attributes of the character: white space, alphabetic, numeric, string quote, and comment character. Each character can have zero or more of these attributes.
In addition, an instance has four flags. These flags indicate:
A typical application first constructs an instance of this class, sets up the syntax tables, and then repeatedly loops calling the nextToken method in each iteration of the loop until it returns the value TT_EOF.
The first program:
import java.io.*;
public class St_1 {
public static void main( String args[] ) {
StreamTokenizer input;
if ( args.length > 1 ) {
System.err.println("Usage: java St [file-name]");
System.exit(1);
}
try {
String line;
if ( args.length == 1 )
input = new StreamTokenizer( new FileReader(args[0]) );
else
input = new StreamTokenizer(
new InputStreamReader(System.in) );
while ( input.TT_EOF != input.nextToken() ) {
System.out.println(input.lineno() + ": "
+ input.toString());
}
}
catch ( FileNotFoundException e) {
System.out.println(e.getMessage());
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( Exception e) {
System.out.println("Exception occurred: " + e.getMessage() );
e.printStackTrace();
}
}
}
Source Code: Src/9_was/St_1.java
Result:
% head -1 /etc/passwd root:x:0:1:Super-User:/:/sbin/sh % head -1 /etc/passwd | java St_1 1: Token[root], line 1 1: Token[':'], line 1 1: Token[x], line 1 1: Token[':'], line 1 1: Token[n=0.0], line 1 1: Token[':'], line 1 1: Token[n=1.0], line 1 1: Token[':'], line 1 1: Token[Super-User], line 1 1: Token[':'], line 1 % java St_1 /etc/passwd | sed 7q 1: Token[root], line 1 1: Token[':'], line 1 1: Token[x], line 1 1: Token[':'], line 1 1: Token[n=0.0], line 1 1: Token[':'], line 1 1: Token[n=1.0], line 1 % java St_1 hello 1: Token[hello], line 1 a b:c d;e 2: Token[a], line 2 2: Token[b], line 2 2: Token[':'], line 2 2: Token[c], line 2 2: Token[d], line 2 2: Token[';'], line 2 2: Token[e], line 2 % java St_1 aa /// 1: Token[aa], line 1 sss // wwww 2: Token[sss], line 2 222 + # 3: Token[n=222.0], line 3 3: Token['+'], line 3 3: Token['#'], line 3
The second program is a begining of a calculator:
import java.io.*;
public class St_2 {
StreamTokenizer input;
public void adjustT() {
input.resetSyntax();
input.commentChar('#'); // comments from #
// to end-of-line
input.wordChars('0', '9'); // parse decimal
// numbers as words
input.wordChars('.', '.');
input.wordChars('+', '+'); // operators as words
input.wordChars('-', '-'); // operators as words
input.wordChars('*', '*'); // operators as words
input.wordChars('/', '/'); // operators as words
input.whitespaceChars(0, ' '); // ignore white space
input.eolIsSignificant(true); // need '\n'
}
public void processInput() throws IOException {
while ( input.TT_EOF != input.nextToken() ) {
if ( input.ttype != input.TT_EOL )
System.out.println(input.lineno() + ": " +
input.sval);
else
System.out.println("Saw EOL");
}
}
public static void main( String args[] ) {
St_2 aSt_2 = new St_2();
if ( args.length > 1 ) {
System.err.println(
"Usage: java St [file-name]");
System.exit(1);
}
try {
String line;
if ( args.length == 1 )
aSt_2.input = new StreamTokenizer(
new FileReader(args[0]) );
else
aSt_2.input = new StreamTokenizer(
new InputStreamReader(System.in) );
aSt_2.adjustT();
aSt_2.processInput();
}
catch ( FileNotFoundException e) {
System.out.println(e.getMessage());
}
catch ( IOException e) {
System.out.println(e.getMessage());
}
catch ( Exception e) {
System.out.println("ExceptionType occurred: " +
e.getMessage() );
e.printStackTrace();
}
}
}
Source Code: Src/9_was/St_2.java
Result:
% java St_2 Saw EOL 2 + 3 1: 2 1: + 1: 3 Saw EOL 2 - 3 2: 2 2: - 2: 3 Saw EOL
A simple calculator:
The first idea for the process loop:
public void processInput() throws IOException {
while ( input.TT_EOF != new Expression(input) ) {
;
}
}
What do you think?
import java.io.BufferedReader;
import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StreamTokenizer;
/** lexical analyzer for arithmetic expressions.
Comments extend from # to end of line.
Words are composed of digits and decimal point(s).
White space consists of control characters and space and is ignored;
however, end of line is returned.
Fixes the lookahead problem for TT_EOL.
*/
public class Scanner extends StreamTokenizer {
/** kludge: pushes an anonymous Reader which inserts
a space after each newline.
*/
public Scanner (Reader r) {
super (new FilterReader(new BufferedReader(r)) {
protected boolean addSpace; // kludge to add space after \n
public int read () throws IOException {
int ch = addSpace ? ' ' : in.read();
addSpace = ch == '\n';
return ch;
}
});
resetSyntax();
commentChar('#'); // comments from # to end-of-line
wordChars('0', '9'); // parse decimal numbers as words
wordChars('.', '.');
whitespaceChars(0, ' '); // ignore control-* and space
eolIsSignificant(true); // need '\n'
}
}
Source Code: Src/9_e/Scanner.java
/*
* Thanks to ats
*/
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.StreamTokenizer;
import java.util.Vector;
/** recognizes, stores, and evaluates arithmetic expressions.
*/
public abstract class Expression {
final static int eol = StreamTokenizer.TT_EOL; // switch use ...
final static int eof = StreamTokenizer.TT_EOF; // must be const :(
final static int word = StreamTokenizer.TT_WORD;
/** reads lines from standard input, parses, and evaluates them
or writes them as a Vector to standard output if -c is set.
@param args if -c is specified, a Vector is written.
*/
public static void main (String args []) {
Scanner scanner = new Scanner(new InputStreamReader(System.in));
try {
do
try {
Number n = Expression.line(scanner);
System.out.println(n.floatValue());
} catch (java.lang.Exception e) {
System.err.println(scanner +": "+ e);
while (scanner.ttype != scanner.TT_EOL
&& scanner.nextToken() != scanner.TT_EOF)
;
} while (scanner.ttype == scanner.TT_EOL);
} catch (IOException ioe) { System.err.println(ioe); }
}
/** indicates parsing errors.
*/
public static class Exception extends java.lang.Exception {
public Exception (String msg) {
super(msg);
}
}
/** recognizes line: sum '\n';
an empty line is silently ignored.
@param s source of first input symbol, may be at end of file.
@return tree for sum, null if only end of file is found.
@throws Exception for syntax error.
@throws IOException discovered on s.
*/
public static Number line (Scanner s) throws Exception, IOException {
for (;;)
switch (s.nextToken()) {
default:
Number result = sum(s);
if (s.ttype != eol) throw new Exception("expecting nl");
return result;
case eol: continue; // ignore empty line
case eof: return null;
}
}
/** recognizes product: term [{ ('*'|'%'|'/') term }];
@param s source of first input symbol, advanced beyond product.
@return tree with evaluators.
@see Expression#sum
*/
public static Number product (Scanner s) throws Exception, IOException {
Number result = term(s);
for (;;)
switch (s.ttype) {
case '*':
s.nextToken();
result = new Node.Mul(result, term(s));
continue;
case '/':
s.nextToken();
result = new Node.Div(result, term(s));
continue;
case '%':
s.nextToken();
result = new Node.Mod(result, term(s));
continue;
default:
return result;
}
}
/** recognizes sum: product [{ ('+'|'-') product }];
@param s source of first input symbol, advanced beyond sum.
@return tree with evaluators.
@see Expression#line
*/
public static Number sum (Scanner s) throws Exception, IOException {
Number result = product(s);
for (;;)
switch (s.ttype) {
case '+':
s.nextToken();
result = new Node.Add(result, product(s));
continue;
case '-':
s.nextToken();
result = new Node.Sub(result, product(s));
continue;
default:
return result;
}
}
/** recognizes term: '('sum')' | Number;
@param s source of first input symbol, advanced beyond term.
@return tree with evaluators.
@see Expression#sum
*/
public static Number term (Scanner s) throws Exception, IOException {
switch (s.ttype) {
case '(':
s.nextToken();
Number result = sum(s);
if (s.ttype != ')') throw new Exception("expecting )");
s.nextToken();
return result;
case word:
result = s.sval.indexOf(".") < 0 ? (Number)new Long(s.sval)
: (Number)new Double(s.sval);
s.nextToken(); return result;
}
throw new Exception("missing term");
}
} // end of class Expression
Source Code: Src/9_e/Expression.java
Result:
% java Expression 2 * ( 1 - 2 ) -2.0 Ep
|
|