|
Second Summer 2002 |
So far we know how to generate data for the user, graphically or
textually. We are also able to get input from the user from the
command line, as a sequence of Strings, or from the
mouse in a graphical, or a graphical user interface, context. Now we want to be able to read text from a file, and from the terminal, and also to write text to a file.
If you want to be able to make phone calls you need to buy a telephone and use it according to the manufacturer's instructions. Same thing with I/O in Java: we just need to know what type of objects we need to work with (and how) in order to read from or write to a file, and read from the terminal.
| Purpose | Input | Output |
| Connection | java.io.FileInputStream |
java.io.FileOutputStream |
| Text Files |
java.io.InputStreamReaderjava.io.BufferedReaderjava.io.StreamTokenizer |
java.io.PrintWriter |
| Data Files | java.io.DataInputStream |
java.io.DataOutputStream |
| Object Files | java.io.ObjectInputStream |
java.io.ObjectOutputStream |
The URLs are:
http://java.sun.com/j2se/1.4/docs/api/java/io/FileInputStream.html http://java.sun.com/j2se/1.4/docs/api/java/io/FileOutputStream.html http://java.sun.com/j2se/1.4/docs/api/java/io/InputStreamReader.html http://java.sun.com/j2se/1.4/docs/api/java/io/BufferedReader.html http://java.sun.com/j2se/1.4/docs/api/java/io/StreamTokenizer.html http://java.sun.com/j2se/1.4/docs/api/java/io/PrintWriter.html http://java.sun.com/j2se/1.4/docs/api/java/io/DataInputStream.html http://java.sun.com/j2se/1.4/docs/api/java/io/DataOutputStream.html http://java.sun.com/j2se/1.4/docs/api/java/io/ObjectInputStream.html http://java.sun.com/j2se/1.4/docs/api/java/io/ObjectOutputStream.html
Let's try to learn how to use these classes one by one.
FileInputStream
InputStreamReader
BufferedReader
StreamTokenizer
System.out
System.in
FileOutputStream
PrintWriter
1. FileInputStream
Find the documentation for it here.
http://java.sun.com/j2se/1.4/docs/api/java/io/FileInputStream.html
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%vi file
oldschool.cs.indiana.edu%ls -l
total 2
-rw------- 1 dgerman 289 Jul 19 12:49 Example.java
-rw------- 1 dgerman 59 Jul 19 12:45 file
oldschool.cs.indiana.edu%cat file
This is a sample
file that has three
lines of text in it.
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
FileInputStream stream = new FileInputStream(args[0]);
stream.close();
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%ls -l
total 3
-rw------- 1 dgerman 793 Jul 19 12:50 Example.class
-rw------- 1 dgerman 289 Jul 19 12:50 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
oldschool.cs.indiana.edu%java Example file
oldschool.cs.indiana.edu%java Example A.java
Something went wrong: java.io.FileNotFoundException: A.java
oldschool.cs.indiana.edu%java Example
Something went wrong: java.lang.ArrayIndexOutOfBoundsException: 0
oldschool.cs.indiana.edu%
Here's a different version, can you see what's different?
import java.io.*;
class Example {
public static void main(String[] args) throws Exception {
FileInputStream stream = new FileInputStream(args[0]);
stream.close();
}
}
So now you know how you can get a connection, and what happens if you're asking
for an inconsistent or incorrect kind of connection. Let's now read the character
one by one and put parens around them when we print them back to the user to see if
we can get inside the contents of the file.
2. InputStreamReader
Find documentation for this kind of objects here.
http://java.sun.com/j2se/1.4/docs/api/java/io/InputStreamReader.html
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
FileInputStream stream = new FileInputStream(args[0]);
InputStreamReader reader = new InputStreamReader(stream);
int data = reader.read();
while (data != -1) {
System.out.print("(" + data + ")");
data = reader.read();
}
stream.close();
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%java Example file
(84)(104)(105)(115)(32)(105)(115)(32)(97)(32)(115)(97)(109)(112)(108)(101)(10\
)(102)(105)(108)(101)(32)(116)(104)(97)(116)(32)(104)(97)(115)(32)(116)(104)(\
114)(101)(101)(10)(108)(105)(110)(101)(115)(32)(111)(102)(32)(116)(101)(120)(\
116)(32)(105)(110)(32)(105)(116)(46)(32)(10)
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
FileInputStream stream = new FileInputStream(args[0]);
InputStreamReader reader = new InputStreamReader(stream);
int data = reader.read();
while (data != -1) {
System.out.print("(" + (char)data + ")");
data = reader.read();
}
stream.close();
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%java Example file
(T)(h)(i)(s)( )(i)(s)( )(a)( )(s)(a)(m)(p)(l)(e)(
)(f)(i)(l)(e)( )(t)(h)(a)(t)( )(h)(a)(s)( )(t)(h)(r)(e)(e)(
)(l)(i)(n)(e)(s)( )(o)(f)( )(t)(e)(x)(t)( )(i)(n)( )(i)(t)(.)( )(
)oldschool.cs.indiana.edu%
So you see how you can get to the characters, by first getting their integer
codes and then converting them into char data. Now let's see how
we can get a whole line of characters at a time.
3. BufferedReader
Find documentation about this kind of objects here.
http://java.sun.com/j2se/1.4/docs/api/java/io/BufferedReader.html
oldschool.cs.indiana.edu%ls -l
total 2
-rw------- 1 dgerman 408 Jul 19 13:12 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
FileInputStream stream = new FileInputStream(args[0]);
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader b = new BufferedReader(reader);
String line = b.readLine();
while (line != null) {
System.out.println("(" + line + ")");
line = b.readLine();
}
stream.close();
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%java Example file
(This is a sample)
(file that has three)
(lines of text in it. )
oldschool.cs.indiana.edu%
This was easy and you knew all about it already.
4. StreamTokenizer
Find documentation about these kind of objects here.
http://java.sun.com/j2se/1.4/docs/api/java/io/StreamTokenizer.html
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%ls -l
total 2
-rw------- 1 dgerman 763 Jul 19 13:33 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
FileInputStream stream = new FileInputStream(args[0]);
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader b = new BufferedReader(reader);
StreamTokenizer s = new StreamTokenizer(b);
s.nextToken();
while (s.ttype != StreamTokenizer.TT_EOF) {
if (s.ttype == StreamTokenizer.TT_WORD)
System.out.println("(" + s.sval + ")");
else if (s.ttype == StreamTokenizer.TT_NUMBER)
System.out.println("(" + s.nval + ")");
s.nextToken();
}
stream.close();
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%java Example file
(This)
(is)
(a)
(sample)
(file)
(that)
(has)
(three)
(lines)
(of)
(text)
(in)
(it.)
oldschool.cs.indiana.edu%
EXERCISE
StringTokenizer
on lines returned from a BufferedReader
to achieve same result.
System.out You can read about this kind of objects here. You have used this kind of objects a lot.
http://java.sun.com/j2se/1.4/docs/api/java/lang.System.html6.
System.in You can read about this kind of objects here.
http://java.sun.com/j2se/1.4/docs/api/java/lang.System.html
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader b = new BufferedReader(reader);
System.out.println("Welcome to the Echo program!");
System.out.print("Type: ");
String line = b.readLine();
while (! line.equals("quit")) {
System.out.println("You typed: " + line);
System.out.print("Type: "); line = b.readLine();
}
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
} finally {
System.out.println("Good-bye.");
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%java Example
Welcome to the Echo program!
Type: Test
You typed: Test
Type: Hello!
You typed: Hello!
Type: I am talking to you.
You typed: I am talking to you.
Type: Hi there.
You typed: Hi there.
Type: quit
Good-bye.
oldschool.cs.indiana.edu%
6. FileOutputStream You can read the documentation about this kind of objects here.
http://java.sun.com/j2se/1.4/docs/api/java/io/FileOutputStream.html
oldschool.cs.indiana.edu%ls -l
total 2
-rw------- 1 dgerman 667 Jul 19 13:51 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%pico Example.java
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%ls -l
total 2
-rw------- 1 dgerman 350 Jul 19 14:00 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
FileOutputStream stream = new FileOutputStream(args[0]);
stream.close();
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
} finally {
System.out.println("Good-bye.");
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%java Example
Something went wrong: java.lang.ArrayIndexOutOfBoundsException: 0
Good-bye.
oldschool.cs.indiana.edu%java Example file.out
Good-bye.
oldschool.cs.indiana.edu%ls -l
total 3
-rw------- 1 dgerman 850 Jul 19 14:00 Example.class
-rw------- 1 dgerman 350 Jul 19 14:00 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
-rw------- 1 dgerman 0 Jul 19 14:01 file.out
oldschool.cs.indiana.edu%
7. PrintWriter Read the documentation about this kind of objects here.
http://java.sun.com/j2se/1.4/docs/api/java/io/PrintWriter.html
oldschool.cs.indiana.eduls -l
total 2
-rw------- 1 dgerman 701 Jul 19 14:09 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
oldschool.cs.indiana.edu%vi Example.java
oldschool.cs.indiana.edu%cat Example.java
import java.io.*;
class Example {
public static void main(String[] args) {
try {
FileOutputStream stream = new FileOutputStream(args[0]);
PrintWriter p = new PrintWriter(stream, true);
BufferedReader b = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Hello, please type: "); String line = b.readLine();
while (! line.equals("quit")) {
p.println(line);
System.out.print("Thanks, please go on: "); line = b.readLine();
}
stream.close();
} catch (Exception e) {
System.out.println("Something went wrong: " + e.toString());
} finally {
System.out.println("Good-bye.");
}
}
}
oldschool.cs.indiana.edu%javac Example.java
oldschool.cs.indiana.edu%java Example file.out
Hello, please type: I am typing lines that
Thanks, please go on: my program should write
Thanks, please go on: to the file that I have
Thanks, please go on: indicated on the command
Thanks, please go on: line, that is: file.out
Thanks, please go on: quit
Good-bye.
oldschool.cs.indiana.edu%ls -l
total 5
-rw------- 1 dgerman 1362 Jul 19 14:09 Example.class
-rw------- 1 dgerman 701 Jul 19 14:09 Example.java
-rw------- 1 dgerman 59 Jul 19 12:50 file
-rw------- 1 dgerman 120 Jul 19 14:10 file.out
oldschool.cs.indiana.edu%cat file.out
I am typing lines that
my program should write
to the file that I have
indicated on the command
line, that is: file.out
oldschool.cs.indiana.edu
That's basically it, as far as text goes.
We don't know it yet, but we have almost everything worked out.
Here now is a worm program. It keeps track of how many times it has been called and when. It then saves itself in a file. The blue code is the added level of complexity in the structure of the worm.
Note that the I/O is the same, regardless of the complexity of Worm
objects (the blue code adds an instance variable of type Vector to their
definition, but the I/O part does not care). This is not an example of a self-referential
object. Its actual purpose is to point out the significant advantages that object
serialization has to offer. You see how easy it is to write and read whole objects.
frilled.cs.indiana.edu%cat Worm.java
import java.util.*;
import java.io.*;
class Worm implements Serializable {
int calls; Vector v = new Vector();
public static void main(String[] args) {
Worm w;
try {
FileInputStream fis = new FileInputStream("Worm");
ObjectInputStream ois = new ObjectInputStream(fis);
w = (Worm)ois.readObject();
ois.close();
} catch (Exception e) {
w = new Worm();
}
System.out.println(
"I have been called " + w.calls + " times."
);
w.calls += 1;
w.v.addElement(new Date());
for (int i = 0; i < w.v.size(); i++)
System.out.println(
"***(" + w.v.elementAt(i).toString() + ")***"
);
try {
FileOutputStream fos = new FileOutputStream("Worm");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(w);
oos.close();
} catch (Exception e) {
System.out.println("Something went wrong when writing.");
}
}
}
frilled.cs.indiana.edu%javac Worm.java
frilled.cs.indiana.edu%java Worm
I have been called 0 times.
***(Wed Jul 31 02:30:11 EST 2002)***
frilled.cs.indiana.edu%ls -ld Worm*
-rw------- 1 dgerman 265 Jul 31 02:30 Worm
-rw------- 1 dgerman 1586 Jul 31 02:30 Worm.class
-rw------- 1 dgerman 938 Jul 31 02:29 Worm.java
frilled.cs.indiana.edu%java Worm
I have been called 1 times.
***(Wed Jul 31 02:30:11 EST 2002)***
***(Wed Jul 31 02:30:36 EST 2002)***
frilled.cs.indiana.edu%java Worm
I have been called 2 times.
***(Wed Jul 31 02:30:11 EST 2002)***
***(Wed Jul 31 02:30:36 EST 2002)***
***(Wed Jul 31 02:30:42 EST 2002)***
frilled.cs.indiana.edu%
So the code is here:
import java.util.*;
import java.io.*;
class Worm implements Serializable {
int calls; Vector v = new Vector();
public static void main(String[] args) {
Worm w;
try {
FileInputStream fis = new FileInputStream("Worm");
ObjectInputStream ois = new ObjectInputStream(fis);
w = (Worm)ois.readObject();
ois.close();
} catch (Exception e) {
w = new Worm();
}
System.out.println(
"I have been called " + w.calls + " times."
);
w.calls += 1;
w.v.addElement(new Date());
for (int i = 0; i < w.v.size(); i++)
System.out.println(
"***(" + w.v.elementAt(i).toString() + ")***"
);
try {
FileOutputStream fos = new FileOutputStream("Worm");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(w);
oos.close();
} catch (Exception e) {
System.out.println("Something went wrong when writing.");
}
}
}
We now need to talk about Exceptions. (In fact, we should have
started with exceptions, then move to file input, which is a likely source of
Exceptions). Exceptions provide
Exceptions in Java are objects. All exception types must extend the
Java language class Throwable or one of its subclasses.
(By convention, new exception types extend Exception
rather than Throwable). All exceptions you create should
extend Exception, making them checked exceptions.
Java exceptions are primarily
RuntimeException and Error, thereby
creating Here's what's being thrown:tucotuco.cs.indiana.edu% vi One.java
tucotuco.cs.indiana.edu% cat One.java
class One { public static void main(String[] args) { One one = new One(); one.run(); } void run() { int a = 10, b = 0, c; c = a / b; // oops! System.out.println(a + " / " + b + " = " + c); } }
tucotuco.cs.indiana.edu% javac One.java
tucotuco.cs.indiana.edu% java One
java.lang.ArithmeticException: / by zero at One.run(Compiled Code) at One.main(Compiled Code)
tucotuco.cs.indiana.edu%
java.lang.Object
|
+----java.lang.Throwable
|
+----java.lang.Exception
|
+----java.lang.RuntimeException
|
+----java.lang.ArithmeticException
(I am sure you can look this up by now).
Here's a longer and session in which we create and throw our
own BadArgumentException:
The lines marked in red are exceptions thrown when our contrived bug kicks in.tucotuco.cs.indiana.edu% vi Two.java
tucotuco.cs.indiana.edu% cat Two.java
class Two { public static void main(String[] args) { System.out.println("The main method started..."); Two two = new Two(); for (int i = -3; i <= 3; i++) { try { int result = two.factorial(i); System.out.println(" Factorial of " + i + " is: " + result); } catch (BadArgumentException e) { System.out.println(" Factorial was called with negative input: " + e.toString()); } } System.out.println("... main method ends."); } int factorial(int n) throws BadArgumentException { if (n < 0) throw new BadArgumentException(n); if (n == 0) return 1; return n * factorial(n - 1); } } class BadArgumentException extends Exception { int arg; BadArgumentException (int arg) { this.arg = arg; } public String toString() { return " " + arg; } }
tucotuco.cs.indiana.edu% ls -l
total 4 -rw-r--r-- 1 dgerman students 220 Mar 20 19:20 One.java -rw-r--r-- 1 dgerman students 848 Mar 20 20:05 Two.java
tucotuco.cs.indiana.edu% javac Two.java
tucotuco.cs.indiana.edu% ls -l
total 10 -rw-r--r-- 1 dgerman students 515 Mar 20 20:07 BadArgumentException.class -rw-r--r-- 1 dgerman students 220 Mar 20 19:20 One.java -rw-r--r-- 1 dgerman students 1087 Mar 20 20:07 Two.class -rw-r--r-- 1 dgerman students 848 Mar 20 20:05 Two.java
tucotuco.cs.indiana.edu% java Two
The main method started... Factorial was called with negative input: -3 Factorial was called with negative input: -2 Factorial was called with negative input: -1 Factorial of 0 is: 1 Factorial of 1 is: 1 Factorial of 2 is: 2 Factorial of 3 is: 6 ... main method ends.
tucotuco.cs.indiana.edu% vi Two.java
tucotuco.cs.indiana.edu% cat Two.java
class Two { public static void main(String[] args) { System.out.println("The main method started..."); Two two = new Two(); for (int i = -3; i <= 3; i++) { try { int result = two.factorial(i); System.out.println(" Factorial of " + i + " is: " + result); } catch (BadArgumentException e) { System.out.println(" Factorial was called with negative input: " + e.toString()); } } System.out.println("... main method ends."); } int factorial(int n) throws BadArgumentException { if (n < 0) throw new BadArgumentException(n); // if (n == 0) return 1; return n * factorial(n - 1); } } class BadArgumentException extends Exception { int arg; BadArgumentException (int arg) { this.arg = arg; } public String toString() { return " " + arg; } }
tucotuco.cs.indiana.edu% javac Two.java
tucotuco.cs.indiana.edu% java Two
The main method started... Factorial was called with negative input: -3 Factorial was called with negative input: -2 Factorial was called with negative input: -1 Factorial was called with negative input: -1 Factorial was called with negative input: -1 Factorial was called with negative input: -1 Factorial was called with negative input: -1 ... main method ends.
tucotuco.cs.indiana.edu%