Skip to main content

more options

Lab: Reading and writing files

This purpose of this little assignment is to help you become familiar with input/output (I/O) in Java. When you complete it, bring a listing of your program to a consultant in the ACCEL lab, who will check your work briefly and then record that you have done this assignment.

Begin by perusing section 5.9 of the text. Better yet, listen to the lectures on lesson page 5-7 of the ProgramLive CD. The lectures are much clearer than the paper version. We also provide some basic information below.

Start this lab by downloading file LabIO.java into a directory, opening it in DrJava, and compiling. You will also need this text file: test.txt.

Streams

A "stream" is a sequence of data values that is processed --either read or written-- from beginning to end. When the data is being read, or input, the stream is called an "input stream"; when it is being written, or output, the stream is called an "output stream". Input/output of streams is done in Java using classes in package java.io.

The basic way to create an input stream for a file is by creating an instance of class FileReader:

FileReader fr= new FileReader(<an arg that describes what file to read>);

And the standard way to read using FileReader fr is to read one character at a time, using function

fr.read()

This is too low-level for us. We would like to be able to read not one character at a time but one line at a time. For this, we use class BufferedReader. Instead of the above, use this:

FileReader fr= new FileReader(<an arg that describes what file to read>);
BufferedReader br= new BufferedReader(fr);

Then, execution of

String lin= br.readLine();

reads the next line of the file and stores it in variable lin --if there are no more lines to read, null is stored in lin. We will see how to use this later.

Using a JFileChooser dialog box

In order to read a file, you have to indicate which file should be read. The easiest way to do this is to use a dialog window to navigate to the appropriate directory and select the file. For this, we use an instance of class JFileChooser, in package javax.swing. Execute the following in the Interactions pane:

br= LabIO.getReader(null);

[Note, if you get a message that says br is undefined, open menu item Edit->Preferences, select "Interactions Pane in the left column, and uncheck box "Require variable type".]

A dialog box opens. Its title is "Choose input file". And it allows you to navigate anywhere you want and then select a file. Do a bit of navigating and select a file. Then take a look at the declaration of function getReader(Sring). Here is what it does:

1. Declare local variable jd of class JFileChooser.

2. Store in jd a new instance of class JFileChooser. In the new-expression new JFileChooser(), you have no control over the directory that appears in dialog window initially. In the new-expression new JFileChooser(p), string p is supposed to be a path on your computer of the directory to open in the dialog window. This alternative allows you to dispense with a lot of navigating.

3. Set the title of jd to "Choose input file".

4. Open a dialog window on your monitor —jd.showOpenDialog(null);. The program pauses until you have closed it. Nothing happens until you have chosen a file (or canceled the interaction).

5. If the selected path is null (probably because the user canceled the dialog), return null.

6. Create a new FileReader with the file that you selected (its name is jd.getSelectedFile()) as the argument and store its name in fr.

7. Create and return a BufferedReader that is attached to fr.

The function call for obtaining the next line from a BufferedReader br is:

br.readLine() // = the next line of BufferedReader br ---null if no more lines

In the Interactions pane, you can continue to evaluate br.readLine(). Each time you do it, the next line of the file you selected is printed. Try it.

Processing the lines of a file

Function lines in class LabIO illustrates the basic way of processing the lines of a file given by a BufferedReader. In the Interactions pane, put a call on this method and let it read some file --you will see how many lines the file has in it.

Study this method. Any loop that you write that processes a file should be similar to this one --the "processing" of each line will change, but the basic structure of the loop that does the processing will not. Note that this method contains a while-loop. Here are important points:

  • The first line is read before the while-loop and stored in variable lin. lin will be null if the file is empty.
  • The loop stops when lin is null, indicating that there are no more lines in the file.
  • The repetend (1) processes the line given by variable lin, in this case simply increasing n, and (2) reads the next line into lin.

The header of the method contains a new construct: throws IOException. It is needed because function br.readLine() might create some sort of I/O (input/output) error, and this is how we handle it. If Java gives a syntax error message indicating that such a "throws clause" is needed, just put it in. Otherwise, don't concern yourself with the throws clause.

Write your own procedure

Complete procedure checkFile according to its specification (use System.out.println(...); to print a line). Test the function on the text file test.txt, which you obtained at the beginning of the lab.

Writing files

Writing files is not much different from reading them. Look at Sec 5.10 on page 207 of the text --and the accompanying material in ProgramLive-- for information. Fig. 5.7 contains method getWriter, which uses a dialog window to obtain a PrintStream that can be used to write a new file. Fig. 5.8 contains a method to use a dialog window to obtain a PrintStream that can be used to append to an existing file --did you know you could do that?

if variable ps contains the name of a PrintStream object, then

ps.println(s)

can be used to write String s followed by the character '\n' on the file associated with object ps.

We have placed method getWriter in class LabIO for you. Study it; make sure you understand what each statement is doing.

Write your own procedure

Complete procedure writeFile so that it implements its specification. You can test it using calls in the interactions pane like this:

LabIO.writeFile(new String[]{"one", "two", "33333333", "", "five"});

Be careful! It is easy when using the dialog window to choose an existing file and then to overwrite that file! You probably don't want this to happen. Be careful.

Show file LabIO.java to a consultant

When you have completed this lab, either print out file LabIO.java or put it on a USB memory stick; then, show it to a consultant in the ACCEL lab during consultant hours. The consultant is instructed to look carefully at procedures checkFile and writeFile. Procedure checkFile must process the lines of the file in a while-loop the way procedures lines does. If there are any errors, or if the consultant sees something inappropriate, they will ask you to revise and come back another day.