Java FILE INPUT AND OUTPUT Chapter 16
Java FILE INPUT AND OUTPUT Chapter 16
CHAPTER
16
FILE INPUT AND OUTPUT
In this chapter, you will:
♦ Use the File class
♦ Understand data file organization and streams
♦ Use streams
♦ Write to and read from a file
♦ Write formatted file data
♦ Read formatted file data
♦ Use a variable filename
♦ Create random access files
Haven’t I seen you spending a lot of time at the keyboard lately?” asks
Lynn Greenbrier one day at Event Handlers Incorporated.
“I’m afraid so,” you answer. “I’m trying to write a program that displays a
month’s scheduled events, one at a time. Every time I run it, I have to enter
the data for every event—the host’s name, the number of guests, and so on.”
“You’re typing all the data over and over again?” Lynn asks in disbelief. “It’s
time for me to show you how to save data to a file.”
577
16 Chapter A4758 5/3/04 4:52 pm Page 578
For convenience, the data file used in this example is stored on a floppy disk.
However, business files are usually stored on a hard disk, either locally or on
Tip a network server. No matter where a data file is physically located, the process
of saving and retrieving the file is the same.
3. Click the View Event button again to view the data for five additional
events. Click the Close button to exit the program at any time. The program
will also exit automatically when you reach the end of the stored data file.
Although their contents vary, files have many common characteristics—each file occu-
pies a section of disk (or other storage device) space, has a name and a specific time of
creation.You can use Java’s File class to gather file information. The File class does not
provide any opening, processing, or closing capabilities for files. Rather, you use the File
class to obtain information about a file, such as whether it exists or is open, its size, and
its last modification date.
You must include the statement import java.io.* in any program that uses the File
class. The java.io package contains all the classes you use in file processing. The File class
is a direct descendant of the Object class.You can create a File object using a constructor
that includes a filename; for example, File someData = new File("data.txt");,
where data.txt is a file on the default disk drive.You can also specify a path for the file, as
in File someData = new File("A:\\Chapter.16\\data.txt");, in which the
argument to the constructor contains a disk drive and path. Table 16-1 lists some useful
File class methods.
Tip
Recall that the backslash (\) is used as part of an escape sequence in Java.
You must type two backslashes to indicate a single backslash to the operat-
Tip ing system. You learned about the escape sequence in Chapter 2.
Next you will write a class that examines a file and prints appropriate messages con-
cerning its status.
16 Chapter A4758 5/3/04 4:52 pm Page 580
Next you will change the program to test for a file that does not exist.
To check for a nonexistent file:
1. Open the CheckFile.java file from the Chapter.16 folder in your text edi-
tor, and then immediately save it as CheckFile2.java.
2. Change the class name to CheckFile2.
3. Change the filename in the File constructor so that it refers to a nonexistent file:
FileƒmyFileƒ=ƒnewƒFile("nodata.txt");
4. Save the file, and then compile and run the program. Unless you have a file
named nodata.txt on your Student Disk, the output looks like Figure 16-3.
16
Figure 16-3 Output of the CheckFile2 program
In the preceding steps, the program found the file named data.txt because the file
was physically located in the current directory from which you were working. You
can check the status of files in other directories by using a File constructor with two
String arguments. The first String represents a path to the filename, and the second
String represents the filename. For example, File someFile = new File("\\
com\\EventHandlers","data.txt"); refers to the data.txt file located in the
EventHandlers folder within the com folder in the root directory.
Next you will create a second data file so that you can compare its size and time stamp
with the data.txt file.
16 Chapter A4758 5/3/04 4:52 pm Page 582
Because you can erase data from files, some programmers prefer the term
persistent storage over permanent storage. In other words, you can remove
Tip data so it is not permanent, but the data remains in the file even when the
computer loses power, so, unlike RAM, the data will persist, or persevere.
Data used by businesses is stored in a data hierarchy, as shown in Figure 16-5.The small-
est, useful piece of data that is of interest to most people is the character. A character is
any one of the letters, numbers, or other special symbols, such as punctuation marks, you
can read and to which you can assign meaning. Characters are made up of bits (the zeros
and ones that represent computer circuitry), but people who use data are not concerned
with whether the internal representation for an A is 01000001 or 10111110.
Java uses Unicode to represent its characters. You first learned about Unicode
Tip
in Chapter 2.
16
When businesses use data, they group characters into fields. A field is a group of char-
acters that has some meaning. For example, the characters T, o, and m might represent
your first name. Other data fields might represent items such as last name, Social Security
number, zip code, and salary.
16 Chapter A4758 5/3/04 4:52 pm Page 584
Characters: B r o w n
Fields are grouped together to form records. An individual’s first and last names, Social
Security number, zip code, and salary represent that individual’s record.When program-
ming in Java, you have created many classes, such as an Employee class or a Student class.
You can think of the data typically stored in each of these classes as a record.These classes
contain individual variables that represent data fields. A business’s data records usually
represent a person, item, sales transaction, or some other concrete object or event.
Records are grouped to create files. Files consist of related records, such as a company’s
personnel file that contains one record for each company employee. Some files have only
a few records; perhaps your professor maintains a file for your class with 25 records—one
record for each student. Other files contain thousands or even millions of records. For
example, a large insurance company maintains a file of policyholders, and a mail-order
catalog company maintains a file of available items.
Before a program can use a data file, the program must open the file. Similarly, when
you finish using a file, the program should close the file. If you fail to close an input file—
that is, a file from which you are reading data, there usually are not any serious conse-
quences; the data still exists in the file. However, if you fail to close an output file—that
is, a file to which you are writing data, the data may become inaccessible. You should
always close every file you open, and you should close the file as soon as you no longer
need it.When you leave a file open for no reason, you use computer resources and your
computer’s performance suffers. Also, particularly within a network, another program
might be waiting to use the file.
While people view files as a series of records with each record containing data fields, Java
views files as a series of bytes. When you perform an input operation in a program, you
can picture bytes flowing into your program from an input device through a stream,
which functions as a pipeline or channel.When you perform output, some bytes flow out
of your program through another stream to an output device, as shown in Figure 16-6.
A stream is an object, and like all objects, streams have data and methods. The methods
allow you to perform actions such as opening, closing, and flushing (clearing) the stream.
16 Chapter A4758 5/3/04 4:52 pm Page 585
INPUT
PROGRAM
OUTPUT
Most streams flow in only one direction; each stream is either an input or output stream.
You might open several streams at once within your program. For example, three streams
are required by a program that reads a data disk. One input stream checks the data for
invalid values, and then one output stream writes some records to a file of valid records;
another output stream writes other records to a file of invalid records.
Random access files use streams that flow in two directions. You will use a
random access file later in this chapter.
Tip
USING STREAMS
Figure 16-7 shows a partial structure of Java’s Stream classes; it shows that InputStream
and OutputStream are subclasses of the Object class. InputStream and OutputStream
are abstract classes that contain methods for performing input and output. As abstract
classes, these classes contain methods that must be overridden in their child classes.The
capabilities of the most commonly used classes that provide input and output are sum-
marized in Table 16-2.
Table 16-2 Description of selected classes used for input and output
Class Description
InputStream Abstract class containing methods for performing input
OutputStream Abstract class containing methods for performing output
16
FileInputStream Child of InputStream that provides the capability to read from
disk files
FileOutputStream Child of OutputStream that provides the capability to write to
disk files
PrintStream Child of FilterOutputStream, which is a child of OutputStream;
PrintStream handles output to a system’s standard (or default)
output device, usually the monitor
BufferedInputStream Child of FilterInputStream, which is a child of InputStream;
BufferedInputStream handles input from a system’s standard (or
default) input device, usually the keyboard
16 Chapter A4758 5/3/04 4:52 pm Page 586
Object
|
+--InputStream
| |
| +--FileInputStream
| |
| +--FilterInputStream
| |
| +--DataInputStream
| |
| +--BufferedInputStream
|
+--OutputStream
| |
| +--FileOutputStream
| |
| +--FilterOutputStream
| |
| +--DataOutputStream
| |
| +--BufferedOutputStream
| |
| +--PrintStream
|
+--RandomAccessFile
Java’s System class declares a PrintStream object. This object is System.out, which you
have used extensively in this book. Besides System.out, the System class defines an addi-
tional PrintStream object named System.err. The output from System.err and
System.out can go to the same device; in fact, System.err and System.out are both
directed to the command line on the monitor.The difference is that System.err usually
is reserved for error messages, and System.out is reserved for valid output.You can direct
either System.err or System.out to a new location, such as a disk file or printer. For
example, you might want to keep a hard copy log of the error messages generated by a
program, but direct the standard output to a disk file.
Figure 16-7 shows that the InputStream class is parent to FilterInputStream, which is
parent to BufferedInputStream. The object System.in is a BufferedInputStream object.
The System.in object captures keyboard input. Recall that you have used this object
with its read() method. A buffer is a small memory location that you use to hold data
temporarily. The BufferedInputStream class allows keyboard data to be held until the
user presses [Enter]. That way, the user can backspace over typed characters to change
the data before the program stores it.This allows the operating system—instead of your
program—to handle the complicated tasks of deleting characters as the user backspaces,
and then replacing the deleted characters with new ones.
16 Chapter A4758 5/3/04 4:52 pm Page 587
Using a buffer to hold input or output improves program performance. Input and
output operations are relatively slow compared to computer processor speeds.
Tip Holding input or output until there is a “batch” makes programs run faster.
You can create your own InputStream and OutputStream objects and assign to them
System.in and System.out, respectively. Then you can use the InputStream’s read()
method to read in one character at a time from the location you choose. The read()
method returns an integer that represents the Unicode value of the typed character; it
returns a value of -1 when it encounters an end-of-file condition, known as EOF.
You can also identify EOF by throwing an EOFException. You will use this
technique later in this chapter.
Tip
Next you will create InputStream and OutputStream objects so you can read from the
keyboard and write to the screen. Of course, you have already written many programs
that read from the keyboard and write to the screen without using these objects. By
using them here with the default input/output devices, you can easily modify the
InputStream and OutputStream objects at a later time; then you can use whatever input
and output devices you choose.
To create a program that reads from the keyboard and writes to the screen:
1. Open a new file in your text editor, and then type the following first few
lines of a program that will allow a user to input data from the keyboard and
then will echo that data to the screen. The class name is
ReadKBWriteScreen:
importƒjava.io.*;
publicƒclassƒReadKBWriteScreen
{
2. Add the following header and opening curly brace for the main() method.
The main() method throws an IOException because you will perform input
and output operations. 16
publicƒstaticƒvoidƒmain(String[]ƒargs)ƒthrowsƒIOException
{
3. Enter the following code to declare InputStream and OutputStream objects,
as well as an integer to hold each character the user types:
InputStreamƒistream;
OutputStreamƒostream;
intƒc;
4. Enter the following code to assign the System.in object to istream, and the
System.out object to ostream. Then add a prompt telling the user to type
some characters.
16 Chapter A4758 5/3/04 4:52 pm Page 588
istreamƒ=ƒSystem.in;
ostreamƒ=ƒSystem.out;
System.out.println("Typeƒsomeƒcharactersƒ");
5. Use the following try block to read from the file. If an IOException occurs,
you can print an appropriate message. Within the try block, execute a loop
that reads from the keyboard until the end-of-file condition occurs (when the
read() method returns -1). While there is not an end-of-file condition, send
the character to the ostream object.
Tip
try
{
ƒƒƒƒƒƒwhile((cƒ=ƒistream.read())ƒ!=ƒ-1)
ƒƒƒƒƒƒƒƒƒƒƒƒƒostream.write(c);
}
6. Use the following catch block to handle any IOException:
catch(IOExceptionƒe)
{
ƒƒƒƒƒƒƒSystem.out.println("Error:ƒ"ƒ+ƒe.getMessage());
}
7. Regardless of whether an IOException occurs, you want to close the streams.
Use the following finally block to ensure that the streams are closed:
finally
{
ƒƒƒƒƒƒƒistream.close();
ƒƒƒƒƒƒƒostream.close();
}
8. Add a closing curly brace for the main() method and another for the class.
9. Save the file as ReadKBWriteScreen.java in the Chapter.16 folder on your
Student Disk, and then compile and run the program. At the command line,
type any series of characters and then press [Enter]. As you type characters,
the buffer holds them until you press [Enter], at which time the stored char-
acters echo to the screen. Do not try to end the program yet.
The while loop in the ReadKBWriteScreen program continues until the read()
method returns -1. However, you cannot end the program by typing -1.Typing a minus
sign (-) and a one (1) causes two additional characters to be sent to the buffer, and nei-
ther of those characters represents -1. Instead, you must press [Ctrl] + Z, which forces
the read() method to return -1, and which the operating system recognizes as the end
of the file. Next you will end the ReadKBWriteScreen program.
16 Chapter A4758 5/3/04 4:52 pm Page 589
2. Execute the program again. This time, type a line of characters, press [Enter],
and observe the echoed output. Then type another line, and press [Enter].
You can type as many lines as you want. Press [Ctrl]+Z, and then press
[Enter]. The program will continue to echo your lines to the screen until
you end the program.
Do not press [Ctrl]+C to end the program. Doing so breaks out of the pro-
gram before its completion and does not properly close the files.
Tip
■ You can create a File object passing the filename to the File constructor.
Then you can pass the File object to the constructor of the
FileOutputStream class.
The second method has some benefits—if you create a File object, you can use the File class
methods such as exists() and lastModified() to retrieve file information. In the next set of
steps you will use a FileOutputStream to write keyboard-entered data to a file you create.
Because applets are designed for distribution over the Internet, you are not
allowed to use an applet to write to files on a client’s workstation. Applets
Tip that write to a client’s file could destroy a client’s existing data.
The meaning of the acronym UTF is disputed by various sources. The most
popular interpretations include Unicode Transformation Format, Unicode
Tip Transfer Format, and Unicode Text Format.
importƒjava.io.*;
importƒjava.awt.*;
importƒjava.awt.event.*;
importƒjavax.swing.*;
publicƒclassƒCreateEventFileƒextendsƒJFrame
ƒƒimplementsƒActionListener
{
2. Enter the following code to create a JLabel for the company name and a
Font object to use with the company name:
privateƒJLabelƒcompanyNameƒ=ƒƒ
ƒƒƒnewƒJLabel("EventƒHandlersƒIncorporated");
FontƒbigFontƒ=ƒnewƒFont("Helvetica",ƒFont.ITALIC,ƒ24);
3. Enter the following code to create a prompt that tells the user to enter data,
and JTextFields for the host, date, and guests. Because a host’s name is usually
several characters long, the field for the host’s name should be wider than the
fields for the date and number of guests.
privateƒJLabelƒpromptƒ=ƒ
ƒƒƒnewƒJLabel("Enterƒthisƒmonth'sƒevents");
privateƒJTextFieldƒhostƒ=ƒnewƒJTextField(10);
privateƒJTextFieldƒdateƒ=ƒnewƒJTextField(4);
privateƒJTextFieldƒguestsƒ=ƒnewƒJTextField(4);
4. Enter the following code to create a JLabel for each of the JTextFields.
Include a JButton object that the user can click when a data record is com-
pleted and ready to be written to the data file. Then add a Container to hold
the JFrame components.
privateƒJLabelƒhLabelƒ=ƒnewƒJLabel("Host");
privateƒJLabelƒdLabelƒ=ƒnewƒJLabel("Date");
privateƒJLabelƒgLabelƒ=ƒnewƒJLabel("Guests");
privateƒJButtonƒenterDataButtonƒ=ƒƒƒ
ƒƒƒnewƒJButton("Enterƒdata");
privateƒContainerƒconƒ=ƒgetContentPane();
5. When you write the user’s data to an output file, you will use the 16
DataOutputStream class, so create a DataOutputStream object as follows:
DataOutputStreamƒostream;
6. Save the work you have done so far as CreateEventFile.java in the
Chapter.16 folder on your Student Disk.
Next you will add the CreateEventFile’s constructor to the class. The constructor calls
its parent’s constructor, which is the JFrame class constructor, and passes it a title to use
for the JFrame.The constructor also attempts to open an events.dat file for output. If the
open fails, the constructor’s catch block handles the Exception; otherwise you add all
the JTextFields, JLabel, and JButton Components to the JFrame.
16 Chapter A4758 5/3/04 4:52 pm Page 594
3. After the file is open, use the following code to set the JFrame’s size, choose a
layout manager, and add all the necessary Components to the JFrame:
setSize(320,200);
con.setLayout(newƒFlowLayout());
companyName.setFont(bigFont);
con.add(companyName);
con.add(prompt);
con.add(hLabel);
con.add(host);
con.add(dLabel);
con.add(date);
con.add(gLabel);
con.add(guests);
con.add(enterDataButton);
4. To finish the JFrame constructor, enter the following code to register the
JFrame as a listener for the JButton, make the JFrame visible, and set the
default close operation for the JFrame. Finally, add a closing curly brace for
the constructor.
ƒƒƒenterDataButton.addActionListener(this);
ƒƒƒsetVisible(true);
ƒƒƒsetDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
16 Chapter A4758 5/3/04 4:52 pm Page 595
5. Save the file. Don’t compile the file yet; you will add more code in the next
set of steps.
When the users see the JFrame, they can enter data in each of the available JTextFields.
When users complete a record for a single event, they click the JButton, which causes
the actionPerformed() method to execute.This method must retrieve the text from each
of the JTextFields and write it to a data file in the correct format.You will write a use-
able actionPerformed() method now.
To add the actionPerformed() method to the CreateEventFile program:
1. At the end of the existing code within the CreateEventFile.java file, press
[Enter] to start a new line below the constructor method, and then type the
following header for the actionPerformed() method. Within the method, cre-
ate an integer variable that will hold the number of guests at an event.
publicƒvoidƒactionPerformed(ActionEventƒe1)
{
ƒƒintƒnumGuests;
2. Use a try block to hold the data retrieval and the subsequent file-writing
actions so that you can handle any I/O errors that occur.You will use the
parseInt() method to convert the JTextField guest number to a usable integer, but
you will accept the host and date fields as simple text.You can use the appropri-
ate DataOutputStream methods to write formatted data to the output file.
You first learned about parseInt() and the Integer class in Chapter 7.
Tip
try
{
ƒƒƒnumGuestsƒ=ƒInteger.parseInt(guests.getText());
ƒƒƒostream.writeUTF(host.getText());
ƒƒƒostream.writeUTF(date.getText());
ƒƒƒostream.writeInt(numGuests);
3. Continue the try block by removing the data from each JTextField after it is
16
written to the file. That way, each JTextField will be clear and ready to
receive data for the next record. Notice that to clear the fields, you use a pair
of quotes with no space between them. Then end the try block.
ƒhost.setText("");
ƒdate.setText("");
ƒguests.setText("");
}
4. There are two types of Exceptions that you might want to deal with in this
application. Because the host name and date fields are text, the user can enter
any type of data. However, the guest field must be an integer. When you use
the parseInt() method with data that cannot be converted to an integer (such
16 Chapter A4758 5/3/04 4:52 pm Page 596
3. Type sample data into the JTextFields in the JFrame. Specifically, type Sagami
as the event host, on the 3(rd), with 150 guests. After entering the data into the
three data fields, click the Enter data button.Your data is sent to the file, and
the fields are cleared. Now you can enter a second record (make up your own
record information), and then click the Enter data button again. Repeat this
process until you have entered five data records.While entering at least one
record, type non-numeric data in the guest field. Notice the error message that
displays on the standard error device at the command line.
4. Click the Close button in the CreateEventFile JFrame to close it.
5. Examine your Student Disk using any file-management program or the DOS
command-line directory command, dir. Confirm that your program created
the events.dat data file in the Chapter.16 folder on your Student Disk.You
will write a program to read the file in the next series of steps.
Next you will create a JFrame in which employees of Event Handlers Incorporated can
view each individual record stored in the events.dat file.The user interface will look like
the interface used in the CreateEventFile JFrame, but the user will not enter data within
16 Chapter A4758 5/3/04 4:52 pm Page 598
this JFrame. Instead, the user will click a JButton to see each succeeding record in the
event.dat file.
To create a JFrame for viewing file data:
1. Open a new file in your text editor, and then type the following first few
lines of the ReadEventFile class:
importƒjava.io.*;
importƒjava.awt.*;
importƒjava.awt.event.*;
importƒjavax.swing.*;
publicƒclassƒReadEventFileƒextendsƒJFrameƒ
ƒƒƒimplementsƒActionListenerƒ
{
2. Enter the following code to declare all of the JLabels, JTextFields, and
associated values that will appear in the JFrame. The text of the prompt and
JButton have changed, but these statements basically echo the statements in
the CreateEventFile.java file.
privateƒJLabelƒcompanyNameƒ=ƒ
ƒƒƒnewƒJLabel("EventƒHandlersƒIncorporated");
FontƒbigFontƒ=ƒnewƒFont("Helvetica",ƒFont.ITALIC,ƒ24);
privateƒJLabelƒpromptƒ=ƒƒnewƒ
ƒƒƒJLabel("Viewƒthisƒmonth'sƒevents");
privateƒJTextFieldƒhostƒ=ƒnewƒJTextField(10);
privateƒJTextFieldƒdateƒ=ƒnewƒJTextField(4);
privateƒJTextFieldƒguestsƒ=ƒnewƒJTextField(4);
privateƒJButtonƒviewEventButtonƒ=ƒnewƒ
ƒƒƒJButton("ViewƒEvent");
privateƒJLabelƒhLabelƒ=ƒnewƒJLabel("Host");
privateƒJLabelƒdLabelƒ=ƒnewƒJLabel("Date");
privateƒJLabelƒgLabelƒ=ƒnewƒJLabel("Guests");
privateƒContainerƒconƒ=ƒgetContentPane();
3. Enter the following code to declare a DataInputStream object. Then write
the ReadEventFile constructor method that uses a try...catch block to
open a file. Notice that you can chain the DataInputStream object and a
FileInputStream object using the same technique you used for output. (Note:
If you have stored your event.dat file in a location other than A:\Chapter.16,
then change the location in the FileInputStream constructor in your own
program.)
DataInputStreamƒistream;
publicƒReadEventFile()
{
ƒƒƒsuper("ReadƒEventƒFile");
ƒƒƒtry
ƒƒƒ{
16 Chapter A4758 5/3/04 4:52 pm Page 599
ƒƒƒƒƒƒƒƒƒistreamƒ=ƒnewƒDataInputStream
ƒƒƒƒƒƒƒƒƒƒƒ(newƒFileInputStream
ƒƒƒƒƒƒƒƒƒƒƒ("A:\\Chapter.16\\events.dat"));
ƒƒƒ}
ƒƒƒcatch(IOExceptionƒe)
ƒƒƒ{
ƒƒƒƒƒƒƒƒƒƒSystem.err.println("Fileƒnotƒopened");
ƒƒƒƒƒƒƒƒƒƒSystem.exit(1);
ƒƒƒ}
4. After successfully opening the file, set the JFrame size, layout manager, and
Font for the JFrame as follows:
setSize(325,200);
con.setLayout(newƒFlowLayout());
companyName.setFont(bigFont);
5. Add the JFrame’s Components as follows:
con.add(companyName);
con.add(prompt);
con.add(hLabel);
con.add(host);
con.add(dLabel);
con.add(date);
con.add(gLabel);
con.add(guests);
con.add(viewEventButton);
6. Enter the following code to ensure that the JFrame listens for JButton mes-
sages, to make the JFrame visible, and to set the default close operation:
viewEventButton.addActionListener(this);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
7. Add the closing curly brace for the ReadEventFile constructor.
8. Type the beginning of the following actionPerformed() method. This method
declares variables for the file field data, and then uses a try block to call the 16
appropriate read() method for each field. Each data field then appears in the
correct JTextField.
publicƒvoidƒactionPerformed(ActionEventƒe1)
{
StringƒtheHost,ƒtheDate;
intƒnumGuests;
try
{
ƒƒƒƒtheHostƒ=ƒistream.readUTF();
ƒƒƒƒtheDateƒ=ƒistream.readUTF();
ƒƒƒƒnumGuestsƒ=ƒistream.readInt();
16 Chapter A4758 5/3/04 4:52 pm Page 600
ƒƒƒƒhost.setText(theHost);
ƒƒƒƒdate.setText(theDate);
ƒƒƒƒguests.setText(String.valueOf(numGuests));
}
9. Code the following two catch blocks for the try block that reads the data
fields. The first catch block catches the EOFException and calls a closeFile()
method. The second catch block catches IOExceptions and exits the pro-
gram if there is a problem with the file. Notice that the Exceptions have
unique names (e2 and e3) because you cannot declare two data items with
the same name within the same method.
catch(EOFExceptionƒe2)
{
ƒƒƒcloseFile();
}
catch(IOExceptionƒe3)
{
ƒƒƒSystem.err.println("Errorƒreadingƒfile");
ƒƒƒSystem.exit(1);
}
10. Add the closing curly brace for the actionPerformed() method.
11. Write the following closeFile() method that closes the DataInputStream
object and exits the program:
publicƒvoidƒcloseFile()
{
ƒƒƒtry
ƒƒƒ{
ƒƒƒƒƒƒƒƒƒƒistream.close();
ƒƒƒƒƒƒƒƒƒƒSystem.exit(0);
ƒƒƒ}
ƒƒƒcatch(IOExceptionƒe)
ƒƒƒ{
ƒƒƒƒƒƒƒƒƒƒSystem.err.println("Errorƒclosingƒfile");
ƒƒƒƒƒƒƒƒƒƒSystem.exit(1);
ƒƒƒ}
}
12. Add the closing curly brace for the class.
13. Save the file as ReadEventFile.java in the Chapter.16 folder on your
Student Disk, and then compile the program using the javac command.
Next you will write a short host program that creates a ReadEventFile JFrame so Event
Handlers employees can examine the existing file of scheduled events.
16 Chapter A4758 5/3/04 4:52 pm Page 601
2. Change the ReadEventFile constructor to the new class name and add an
argument that is a String. The value for this argument will originate from the
first element in the String array (String[]ƒargs) that you have included in
every main() method you have written.
publicƒReadNamedFile(StringƒfileName)
3. Within the try block of the ReadNamedFile constructor, remove the refer-
ence to the filename events.dat, and replace it with the variable filename that
represents the String you will use when you call this constructor. In other
words, change the istream assignment to the following:
istreamƒ=ƒnewƒDataInputStream
ƒƒƒƒ(newƒFileInputStream(fileName));
4. Save the file, and then compile the class.
5. Open a new file in your text editor and type the following program that creates
an instance of the ReadNamedFile class. As the argument to the ReadNamedFile
constructor, use the first (and only) String in the array of String arguments that
you will pass to the main() method from the command line.
importƒjava.io.*;
publicƒclassƒEventFile3
{
ƒƒƒpublicƒstaticƒvoidƒmain(String[]ƒargs)
ƒƒƒ{
ƒƒƒƒƒƒƒƒƒƒReadNamedFileƒrefƒ=ƒnewƒReadNamedFile(args[0]);
ƒƒƒ}
}
6. Save the file as EventFile3.java in the Chapter.16 folder on your Student
Disk, and compile the program.
7. You will test the program using the existing file event.dat. To execute the
program, at the command line type javaƒEventFile3ƒevents.dat. The
program executes, correctly showing you the events in the file as before. One
at a time, view each of the records in the file just like you did in the last set
of steps.
8. Attempt to execute the program using a nonexisting filename, for example
javaƒEventFile3ƒnoSuchFile.dat.You should see the message “File
not opened”.
in the original data-entry order. Businesses store data in sequential order when they use
the records for batch processing, or processing that involves performing the same tasks
with many records, one after the other. For example, when a company produces pay-
checks, the records for the pay period are gathered in a batch and the checks are calcu-
lated and printed in sequence.
For many applications, sequential access is inefficient.These applications, known as real-
time applications, require that a record be accessed immediately while a client is wait-
ing. For example, if a customer telephones a department store with a question about a
monthly bill, the customer service representative does not need to access every customer
account in sequence. With tens of thousands of account records to read, it would take
too long to access the customer’s record. Instead, customer service representatives require
random access files, files in which records can be located in any order. Because they
enable you to locate a particular record directly (without reading all of the preceding
records), random access files are also called direct access files. You can use Java’s
RandomAccessFile class to create your own random access files.
The RandomAccessFile class contains the same read(), write(), and close() methods as
InputStream and OutputStream, but it also contains a seek() method that lets you select a
beginning position within a file before you read or write data. For example, if you declare
a RandomAccessFile object named myFile, then the statement myFile.seek(200);
selects the 200th position within the file. The 200th position represents the 201st byte
because, as with Java arrays, the numbering of file positions begins at zero.The next read()
or write() method will operate from the newly selected starting point.
When you store records in a file, it is often more useful to be able to access the 200th
record, rather than the 201st byte. In this case, you multiply each record’s size by the posi-
tion you want to access. For example, if you store records that are 50 bytes long, you
can access the nth record using the statement myFile.seek((n-1)ƒ*ƒ50);.
When you declare a RandomAccessFile object, you include a filename as you do
with other file objects.You also include r or rw within double quotation marks as a
second argument to indicate that the file is open for reading only (“r”), or for both
reading and writing (“rw”). For example, RandomAccessFileƒmyFileƒ=ƒnew
RandomAccessFile("C:\\Temp\\someData.dat","rw"); opens the 16
someData.dat file so that either the read() or write() method can be used on the file.
This feature is particularly useful in random access processing. Consider a business
with 20,000 customer accounts. When the customer who has the 14,607 th record in
the file acquires a new telephone number, it is convenient to directly access the
14,607th record, the read() method confirms it represents the correct customer, and
then the write() method writes the new telephone number to the file in the loca-
tion the old telephone number was stored previously.You will demonstrate the seek()
method in the next set of steps.
16 Chapter A4758 5/3/04 4:52 pm Page 604
7. Before you run the file, create a datafile.dat file by running the ReadKBWriteFile
program you created earlier in this chapter. At the command line, type
javaƒReadKBWriteFile, and then press [Enter].
8. At the prompt, type This is my random access file. Press [Enter], press
[Ctrl]+Z, and then press [Enter] to end the program. (The y in my is the
10th character you type.)
9. At the command line, run the AccessRandomly program by typing
javaƒAccessRandomly. The output is the tenth character in the file, as
shown in Figure 16-12.
In the AccessRandomly program, only one read() command was issued, yet the program
accessed a byte nine positions into the file.When you access a file randomly, you do not
read all the data that precedes the data you are seeking. Accessing data randomly is one
of the major features that makes large data systems maintainable.
CHAPTER SUMMARY
❒ Files are objects that you store on permanent storage devices, such as floppy disks, 16
CD-ROMs, or external drives.You can use the File class to gather file information.
❒ Data used by businesses generally is stored in a data hierarchy that includes files,
records, fields, and characters.
❒ Java views a file as a series of bytes, and a stream as an object through which input
and output data (in the form of bytes) flow. InputStream and OutputStream are
abstract subclasses of Object that contain methods for performing input and output.
FileInputStream and FileOutputStream provide the capability to read from and write
to files.You can use the InputStream read()method to read in one character at a time.
❒ You can use the DataInputStream and DataOutputStream classes to accomplish for-
matted input and output. The DataOutput interface includes methods such as
16 Chapter A4758 5/3/04 4:52 pm Page 606
REVIEW QUESTIONS
1. Files always .
a. hold software instructions
b. occupy a section of storage space
c. remain open during the execution of a program
d. all of the above
2. The File class enables you to .
a. open a file
b. close a file
c. determine a file’s size
d. all of the above
3. The package contains all the classes you use in file processing.
a. java.file
b. java.io
c. java.lang
d. java.process
4. The statement FileƒaFileƒ=ƒnewƒFile("myFile"); creates a file
.
a. on the disk in drive A
b. on the hard drive (drive C)
c. in the Temp folder on the hard drive (drive C)
d. on the default disk drive
16 Chapter A4758 5/3/04 4:52 pm Page 607
Exercises 609
EXERCISES
1. Create a file using any word-processing program or text editor. Write a program
that displays the file’s name, parent, size, and time of last modification. Save the
program as FileStatistics.java in the Chapter.16 folder on your Student Disk. 16
2. Create two files using any word-processing program or text editor. Write a pro-
gram that determines whether the two files are located in the same folder. Save
the program as SameFolder.java in the Chapter.16 folder on your Student Disk.
3. Write a program that determines which, if any, of the following files are stored in
the Chapter.16 folder of your Student Disk: autoexec.bat, SameFolder.java,
Chap16ReadEventFile.class, and Hello.java. Save the program as
FindSelectedFiles.java in the Chapter.16 folder on your Student Disk.
4. a. Create a JFrame that allows the user to enter a series of friends’ names and
phone numbers and creates a file from the entered data. Save the JFrame as
CreatePhoneList.java in the Chapter.16 folder on your Student Disk. To use
16 Chapter A4758 5/3/04 4:52 pm Page 610
When the user enters an item number, check the number to make sure that it
is valid. If it is valid, write a record that includes item number, quantity, price
each, and total price. Save the program as MailOrderWrite2.java in the
Chapter.16 folder on your Student Disk.
b. Write a program that reads the data file created by the MailOrderWrite2 pro-
gram and displays one record at a time on the screen. Save the program as
MailOrderRead2.java in the Chapter.16 folder on your Student Disk.
7. a. Write a program that allows a user to enter an integer representing a file posi-
tion. Access the requested position within a file and display the character there.
Save the program as SeekPosition.java in the Chapter.16 folder on your
Student Disk.
b. Modify the program created by the SeekPosition program so that you display
the next five characters after the requested position. Save the program as
Seek2.java in the Chapter.16 folder on your Student Disk.
8. a. Write a program that creates a JFrame with text fields for order processing for
a tee-shirt manufacturer. Include JTextFields for size, color, and slogan. Write
each complete record to a file. Save the JFrame as TeeShirtWrite.java in the
Chapter.16 folder on your Student Disk. Write a program named
UseTeeShirt.java that displays the JFrame.
16 Chapter A4758 5/3/04 4:52 pm Page 611
b. Write a program that reads the data file created by the TeeShirtWrite program
and displays one record at a time in a JFrame on the screen. Save the program
as TeeShirtRead.java in the Chapter.16 folder on your Student Disk. Write a
program named UseTeeShirt2.java that displays the JFrame.
9. Write a program that allows the user to type any number of characters into a file.
Then display the file contents backward. Save the program as
ReadBackwards.java in the Chapter.16 folder on your Student Disk.
10. a. Create a JFrame that allows you to enter student data—ID number, last name,
and first name. Include two buttons and instruct the user to click “Grad” or
“Undergrad” after entering the data for each student. Depending on the user’s
choice, write the data to either a file containing graduate students or a separate
file containing undergraduate students. Name the JFrame
GradAndUndergrad.java and create a program named
UseGradAndUndergrad.java that instantiates a JFrame object. Save both files
in the Chapter.16 folder of your Student Disk.
b. Create a JFrame named StudentRead.java that, in turn, accesses all the
records in the graduate and the undergraduate files created in the
GradAndUndergrad program. Write a program named UseStudentRead.java
that instantiates a JFrame object. Save both files in the Chapter.16 folder of
your Student Disk.
11. Each of the following files in the Chapter.16 folder on your Student Disk has
syntax and/or logical errors. In each case, determine the problem and fix the pro-
gram. Notice that DebugSixteen3.java and DebugSixteen4.java have companion
files that are part of each exercise. After you correct the errors, save each file using
the same filename preceded with Fix. For example, DebugSixteen1.java will
become FixDebugSixteen1.java.
a. DebugSixteen1.java
b. DebugSixteen2.java
c. DebugSixteen3.java
d. DebugSixteen4.java
16
CASE PROJECT
Create a data-entry and retrieval system for Mowers Inc., a lawn-mowing service. Use a
Case
JFrame to enter data for the customer’s name and lawn size in square feet. An output file
Project
holds the customer name, lawn size, and fee per mowing—$50 for lawns under 1,000
square feet and $75 for lawns 1,000 square feet or more. Name the JFrame
MowersInc.java and save it in the Chapter.16 folder of your Student Disk. Name the
client program that creates an instance of the JFrame UseMowersInc.java. Retrieve
the created records with a JFrame named MowersInc2.java and a client program
named UseMowersInc2.java.
16 Chapter A4758 5/3/04 4:52 pm Page 612