on Java Filesand HW #3

Download Report

Transcript on Java Filesand HW #3

Session 06
More on Java Files
and HW #3
Java File I/O Example: Echo.java
• echoes all the words in one file to an output
file, one per line.
$ java Echo hamlet.txt hamlet.out
$ less hamlet.out
1604
the
tragedy
of
hamlet
prince
of
denmark
by
william
shakespeare ...
import java.io.*;
import java.util.StringTokenizer;
public class Echo {
public static void main( String[] args ) throws IOException {
String delimiters = " .?!()[]{}|?/&\\,;:-\'\"\t\n\r";
BufferedReader inputFile = new BufferedReader(new FileReader(args[0]) );
PrintWriter
outputFile = new PrintWriter( new FileWriter( args[1] ) );
String buffer = null;
while( true ) {
buffer = inputFile.readLine();
if ( buffer == null ) break;
buffer = buffer.toLowerCase();
StringTokenizer tokens = new StringTokenizer( buffer, delimiters );
while( tokens.hasMoreElements() ) {
String word = tokens.nextToken();
outputFile.println( word );
} // end while
} // end while(true)...
} // end main
} // end class Echo
Working with Standard Input and
Output as Files
• Sometimes, we'd like to give the user an
option of providing a file name or using
standard I/O.
• We can call sort with its own file
argument, or we can pipe the standard
output of one program (cat hamlet.out) as
the standard input to sort.
• How can we make our Java programs do the
same thing?
Streams vs. Readers and Writers
• a stream is a device for transmitting or
receiving a sequence of byte (8-bit) values
– emphasis on reading/writing -- not on data itself
– network and file systems are based on byte unit
• Readers and Writers use 16-bit Unicode
– useful for I/O of textual values as opposed to
binary data such as images, colors, etc.
– for example, BufferedRead has readLine method
Working with Standard Input and
Output as Files
• Standard input is an instance of the
InputStream class and does not respond to
readLine(), which is how we would like to
grab lines of text as Strings.
• Standard output does respond to println()
messages, but it is a PrintStream, which
cannot be stored in a PrintWriter variable.
What can we do?
• We could write duplicate code for the four
different cases. (file-file, file-stdout, stdin-file,
stdin-stdout)
• Every case would look the same except for one
or two lines.
• That doesn't seem to be the correct solution.
• Maybe we can find a way to have them talk to
objects that talk to standard input and output...
A Solution
• Let's take advantage of an object-oriented idea: We ought to
be able to substitute an object with a common interface,
even if somewhat different behavior, in place of one
another, and let the new object fulfill the responsibilities of
the replaced one.
• While BufferedReaders and PrintWriters don't know how to
talk to standard input and output, respectively, we can use a
translator to serve as a go-between.
• Java give us the classes we need: InputStreamReader and
OutputStreamWriter.
import java.io.*;
import java.util.StringTokenizer;
public class EchoStandard {
public static void main( String[] args ) throws IOException {
String delimiters = " .?!()[]{}|?/&\\,;:-\'\"\t\n\r";
BufferedReader inputFile = new BufferedReader(
new InputStreamReader( System.in ) );
PrintWriter outputFile = new PrintWriter(
new OutputStreamWriter( System.out ) );
String buffer = null;
while( true ) {
buffer = inputFile.readLine();
if ( buffer == null ) break;
buffer = buffer.toLowerCase();
StringTokenizer tokens = new StringTokenizer(buffer,delimiters);
while( tokens.hasMoreElements() ) {
String word = tokens.nextToken();
outputFile.println( word );
} // end while
} // end while( true )...
} // end main
} // end class EchoStandard
Echo
BufferedReader inputFile = new BufferedReader(
new FileReader( args[0]) );
PrintWriter
outputFile = new PrintWriter(
new FileWriter( args[1]) );
vs. EchoStandard
BufferedReader inputFile = new BufferedReader(
new InputStreamReader( System.in ) );
PrintWriter outputFile = new PrintWriter(
new OutputStreamWriter( System.out ) );
Exercise
•
Turn Echo.java into EchoV2.java, which behaves just like Echo,
except that it takes two optional command-line arguments: the names
of the input file and output file, respectively.
• If the user omits the second argument, the program writes to standard
output.
• If the user omits both arguments, the program reads from standard
output and writes to standard output. For example:
$ java EchoV2 hamlet.txt hamlet.out
$ less hamlet.out
1604
the
tragedy
of
...
Exercise - More Examples
$ java EchoV2 EchoV2.java
...
$ java EchoV2 hamlet.txt | less
1604
the
tragedy
of
...
(interesting that the pipe “|” is not args[1])
$ java EchoV2
...
$ cat hamlet.txt | java EchoV2 | less
1604
the
tragedy
of
...
Homework #3 - Interacting with Files
• Extend the MemoPad program so it can
save and load memos to and from files
• You’ll need to add two responsibilities to
the MemoDatabase interface:
– loading from a file
– saving to a file
homework03-template.zip
• a new MemoPadApp.java that only creates instances
MyMemoDatabase. It accepts a single optional argument, the
maximum size of the database.
java MemoPadApp // creates a default student database
java MemoPadApp 100 // creates a database with up to 100 memos
• all of the graphics and management classes necessary to compile
your application
• a jar file that will let you run a working program, to see how your
program should work. Just use this command:
java -jar memopad.jar
java -jar memopad.jar 100
// same as first example above
// same as second example above
HW3: Task 1
• Change MemoPadApp.java to create
instances of your MemoDatabase class.
– On Lines 8 and 10, MemoPadApp creates
instances of a MemoDatabase for the
MemoPad. Put your class's name in place of my
class's name. If you named your class
ArrayBasedMemoDatabase, you don't have to
do anything!
HW3: Task 2
• 2. Add empty save() and load() methods to
your MemoDatabase class.
– This should ensure that your class now
implements the extended MemoDatabase
interface.
– Compile and run the program to verify this.
– Of course, the Save and Load buttons won't do
anything yet
HW3: Task 3
• Write the save() method for your class.
– This method takes a String argument, the name of the
file to write. When the user presses the Save to File
button, the MemoPad sends the database a save()
message, with the current value of the Key: field as the
filename.
– You get to decide the format of the data that your
MemoDatabase object writes to the file. For example,
my program writes key/value pairs to a file in this
format:
eugene>>wallingford
philip>>east
HW3: Task 4
• Use your improved class to generate three
to five data files.
– Compile the program and run it several times, each time
saving a new file of memos. Name your files
memos1.dat, memos2.dat, .... This will both enable you
to verify that your method works and generate test data
for the next task!
– Be sure that each file tests something different about
your program. For example, it would be useful to have
an empty file and at least one file with a large number
of memos in it, to test the "boundary conditions" of the
program.
HW3: Task 5
• Write the load() method for your class.
– This method also takes as an argument the
name of a file, taken from the current value of
the Key: field.
– When the user presses the Load from File
button, the MemoPad sends the database a
load() message.
– This method should read records of the same
format as the data written to file by the save()
method.
HW3: Task 6
• Use your new-and-improved class to read
each of your data files.
– Compile the program and run it several times.
– Verify that your program can read each of the
data files you created in Task 4.
– You should also be able to load multiple data
files into the same memo pad. (*)
– Also verify that your program can load and
save several times during the same execution.