Copyright RIT 2009
$Id: writeup.xml,v 1.9 2009/01/05 18:32:18 vcss232 Exp $
In this lab you work with files in Java. You will learn how to write code that opens a file and reads data from it. Since file operations can throw exceptions you will need to handle that also. You will learn to work with files by writing a small utility program that searches for strings in a text file.
Read the documentation for the following classes: FileReader BufferedReader FileWriter BufferedWriter and PrintWriter
Complete the file exercises found by clicking on http://www.cs.rit.edu/~cs1/Exercises/_Files_and_More.
You can also find additional information on I/O from http://java.sun.com/docs/books/tutorial/essential/io/ in the Java tutorial.
Each lab you will do is separated into a set of activities. Each activity has tasks you must complete and submit for credit. Each activity is graded separately.
This activity is a refresher on
command line arguments which were introduced in CS1.
Command line arguments are the words entered
after you type the command name at the Unix prompt. For example,
when you compiled the Rectangle.java and Circle.java
files in Lab 3 you used the command:
|
javac is the name of the command. There are two
command line arguments: Rectangle.java and
Circle.java. Note that spaces separate each argument.
If you want to include spaces in an argument then you must surround that
argument with quotes, as in:
|
Remember that command line arguments in a Java program start
after the name of the program in the command line. For example,
if you type the following command to start the Java program
EchoCommandLine.java:
|
The command line arguments, as seen by the Java program, would be
one, two,three, and four.
To make sure that you understand how to access command line arguments write
a Java program called SumArgs which prints the sum of all of its
integer command line arguments. For each argument, you must
convert it to an integer before adding it to your sum. You can use
the parseInt method in
Integer for this.
For each argument that is not a valid integer, the program will display the following message:
|
where
arg
is the bad command line argument.
(
The quotes do show up in the output.
)
This error message must be sent to
standard error (System.err in Java) instead of
standard out
(System.out in Java). Standard error, which is reserved
for error messages, will display in your terminal window just like
standard out. You have the same formatting
methods available with both outputs. The program must continue summing
the remaining arguments after displaying the error message.
When all the valid integer arguments have been summed, the program will display the following message using standard out:
|
where
sum
is the total of all the valid arguments.
Note that it is possible that none of the arguments are valid, or
you may not get any arguments at all. In these cases sum would
be zero.
For example, if you run your program with the following command:
|
it must generate the following output:
|
with the first three lines going to standard error and the last line going to standard output. (Notice also that 7.6 is not an integer)
Please remember to use javadocs and RCS.
When you are confident that your program works correctly submit it using the following command:
|
For this activity you will write the code to open a file and search for occurrences of a specified string of characters. Your program must print out each line in which it finds the string. The string can exist anywhere on the line. The command line syntax is:
|
The first thing that your program must do is check for the proper number of command line arguments. If this is not correct, display the following error on standard error and then terminate the program:
|
Next the program must process the command line arguments. You will probably want to save the search string in a variable defined in your program. To read the data from the file you will need to construct the appropriate stream object and connect it to the file (remember this program is supposed to read character data).
The java.io, package-summary, package has two inheritance chains that can be used for dealing with files. One chain starts with the abstract classes InputStream and OutputStream, and the second chain starts with Reader and Writer. The Reader and Writer classes are defined for reading from character files. They provide facilities specific to character files, such as, reading a line of input. Use this hierarchy for your work in this activity and the next. As noted in the javadoc for BufferedReader it is advisable to use an object of this class over the lower level FileReader.
Using the file-name command line argument create a FileReader object that is attached to this file and wrap a BufferedReader object around the FileReader. You must handle any exceptions that are thrown by the constructor. If the file is not found, display the following error message on standard error and terminate the program:
|
where ExceptionType is the type of exception you caught and detail-message is what is stored in the detailed message field of the exception object.
Your program must then enter a loop reading lines from the file and looking for search-string in the line (the Java String class contains a method that makes this easy to do). If search-string is found anywhere in the line, display the line on standard output. If you must catch any exceptions, handle them by displaying the following message to standard error and terminating the program:
|
where ExceptionType is the type of exception you caught and detail-message is what is stored in the detailed message field of the exception object.
When you get to the end of the file, close the input stream and end the program.
Please remember to use javadocs and RCS.
Test your program using strings that are in the file and those that are not. Be sure to test the error conditions for the number of command line arguments and file open error. When you are sure that your program works correctly and you have provided correct javadocs, then submit it with the following command:
|
You can see the file that try will use when testing your program by clicking on Auxiliary/road.txt.
You will modify your program from the previous
activity. Copy FindString.java
to a new file FindString2.java.
Rename the class FindString2 as well.
Please remember to use javadocs and RCS.
In this activity you will add a third, optional command line argument. If a third argument is present, it will specify the name of an output file into which all the matching lines will be written. If the third argument is not present, the program must work exactly as before sending the matching lines to standard output. That means this version of the program must be able to write to either a file or the screen.
One way to write either to file or screen is
to use if statements to
select the appropriate output destination
throughout the program.
However, repeated code is cumbersome to maintain and
obscures the logic of the program if overdone.
Therefore you must not solve the
problem this way.
The desired solution described next takes advantage of polymorphism in the Java I/O library. This approach uses overloaded constructors of the PrintWriter class to construct a PrintWriter object that is connected to the appropriate stream or writer for output.
Whether the program is working with a file or
standard output, we want to use an object of type PrintWriter.
You will be able to use the
println() method
in a PrintWriter object to generate output.
Objects of the PrintWriter class can
be constructed from either an
OutputStream or a
Writer object.
This means that any object whose class is a
subclass of either
OutputStream or Writer
can be used to
construct a PrintWriter object.
Since a
BufferedWriter is a
subclass of Writer you can
construct a PrintWriter object using
a BufferedWriter
object, which will allow you to
print() or println()
to the output file.
The System.out object reference is a
PrintStream object,
which is a subclass of OutputStream.
System.out
can be used also to create a PrintWriter object.
Your submission for this activity will get no credit if you use conditionals to handle the print statements within the line processing loop of your program. There must be only ONE object that handles program output. That is, your program must use a single PrintWriter object for output and construct it in a manner appropriate for the current mode of program operation (this mode is based on the command line arguments).
Since the command line arguments to this program have changed from the prior activity, you must change the usage error message generated by the program. If the number of command line arguments is not correct, print the following message to standard error, and terminate the program:
|
NOTE: Square brackets ( [] ) are commonly used in UNIX usage messages to surround optional arguments. the output file name is optional.
If the user specifies that the output from the program must be placed in a file, and an error occurs when the program opens the file or attempts to write to the file, your program must display the following message to standard error and terminate:
|
where
ExceptionType
is the simple name of exception class caught
and detail-message
is the text stored in the message
field of the exception object.
You must close the input and output streams before the program ends.
Please remember to use javadocs and RCS.
Again thoroughly test your program. Check that you have not broken any functionality that was working in activity 2. Make sure that the output file, if specified, is correctly written with the matching lines of text. Verify operation when the output file already exists but is write-protected. When you are sure that your program is working correctly, submit it using the following command:
|
Grade Breakdown: