Transcript Document

Chapter 17 – Files and Streams
Outline
17.1
17.2
17.3
17.4
17.5
17.6
17.7
17.8
17.9
17.10
17.11
17.12
17.13
Introduction
Data Hierarchy
Files and Streams
Class File
Creating a Sequential-Access File
Reading Data from a Sequential-Access File
Updating Sequential-Access Files
Random-Access Files
Creating a Random-Access File
Writing Data Randomly to a Random-Access File
Reading Data Sequentially from a Random-Access File
Case Study: A Transaction-Processing Program
New I/O APIs for the Java Platform
 2003 Prentice Hall, Inc. All rights reserved.
17.1 Introduction
• Files
– Long-term storage of large amounts of data
– Persistent data exists after termination of program
– Files stored on secondary storage devices
• Magnetic disks
• Optical disks
• Magnetic tapes
– Sequential and random access files
 2003 Prentice Hall, Inc. All rights reserved.
17.2 Data Hierarchy
• Smallest data item in a computer is a bit
– Bit can be either 0 or 1
– Bit short for “binary digit”
• Programmers work with higher level data items
–
–
–
–
Decimal digits: (0-9)
Letters: (A-Z and a-z)
Special symbols: (e.g., $, @, %, &, *, (, ), -, +, “, :, ?, /, etc.)
Java uses Unicode characters composed of 2 bytes
• A byte is 8 bits long
• Fields (Java instance variables)
– Composed of characters or bytes
– Conveys meaning
 2003 Prentice Hall, Inc. All rights reserved.
17.2 Data Hierarchy
• Data hierarchy
– Data items in a computer form a hierarchy
• Progresses from bits, to characters, to fields, etc.
• Records
– Composed of several fields
– Implemented as a class in Java
– See Fig. 17.1 for example
• File is a group of related records
– One field in each record is a record key
• Record key is a unique identifier for a record
– Sequential file
• Records stored in order by record key
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.1 Data hierarchy
Judy
Judy
01001010
1
Bit
 2003 Prentice Hall, Inc. All rights reserved.
Sally
Black
Tom
Blue
Judy
Green
Iris
Orange
Randy
Red
Green
File
Record
Field
Byte (ASCII character J)
17.3 Files and Streams
• Java views a file as a stream of bytes (Fig. 17.2)
– File ends with end-of-file marker or a specific byte number
– File as a stream of bytes associated with an object
• Java also associates streams with devices
– System.in, System.out, and System.err
– Streams can be redirected
• File processing with classes in package java.io
–
–
–
–
FileInputStream for byte-based input from a file
FileOutputStream for byte-based output to a file
FileReader for character-based input from a file
FileWriter for character-based output to a file
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.2 Java’s view of a file of n bytes
0
1
2
3
4
5
6
7
8
9
...
...
 2003 Prentice Hall, Inc. All rights reserved.
n-1
end-of-file marker
17.3 Files and Streams
• Buffering
– Improves performance of I/O
– Copies each output to a region of memory called a buffer
– Entire buffer output to disk at once
• One long disk access takes less time than many smaller ones
– BufferedOutputStream buffers file output
– BufferedInputStream buffers file input
 2003 Prentice Hall, Inc. All rights reserved.
17.4 Class File
• Class File
– Provides useful information about a file or directory
– Does not open files or process files
• Fig. 17.3 lists some useful File methods
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.3 File methods
Method
boolean canRead()
Description
Returns true if a file is readable; false otherwise.
boolean canWrite()
boolean exists()
Returns true if a file is writable; false otherwise.
Returns true if the name specified as the argument to the File constructor is a
file or directory in the specified path; false otherwise.
boolean isFile()
Returns true if the name specified as the argument to the File constructor is a
file; false otherwise.
Returns true if the name specified as the argument to the File constructor is a
directory; false otherwise.
Returns true if the arguments specified to the File constructor indicate an
absolute path to a file or directory; false otherwise.
boolean isDirectory()
boolean isAbsolute()
String getAbsolutePath()
Returns a string with the absolute path of the file or directory.
String getName()
String getPath()
String getParent()
Returns a string with the name of the file or directory.
Returns a string with the path of the file or directory.
Returns a string with the parent directory of the file or directory—that is, the
directory in which the file or directory can be found.
long length()
Returns the length of the file, in bytes. If the File object represents a directory,
0 is returned.
Returns a platform-dependent representation of the time at which the file or
directory was last modified. The value returned is useful only for comparison
with other values returned by this method.
long lastModified()
String[] list()
 2003 Prentice Hall, Inc. All rights reserved.
Returns an array of strings representing the contents of a directory. Returns null
if the File object is not a directory.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 17.4: FileTest.java
// Demonstrating the File class.
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
Outline
FileTest.java
Import java.io
package Line 5
public class FileTest extends JFrame
implements ActionListener {
private JTextField enterField;
private JTextArea outputArea;
// set up GUI
public FileTest()
{
super( "Testing class File" );
enterField = new JTextField( "Enter file or directory name here" );
enterField.addActionListener( this );
outputArea = new JTextArea();
ScrollPane scrollPane = new ScrollPane();
scrollPane.add( outputArea );
 2003 Prentice Hall, Inc.
All rights reserved.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Container container = getContentPane();
container.add( enterField, BorderLayout.NORTH );
container.add( scrollPane, BorderLayout.CENTER );
setSize( 400, 400 );
setVisible( true );
Outline
FileTest.java
Line 38
} // end constructor
// display information about file user specifies
public void actionPerformed( ActionEvent actionEvent )
{
File name = new File( actionEvent.getActionCommand() );
// if name exists, output information about it
if ( name.exists() ) {
outputArea.setText( name.getName() + " exists\n" +
( name.isFile() ? "is a file\n" : "is not a file\n" ) +
( name.isDirectory() ? "is a directory\n" :
"is not a directory\n" ) +
( name.isAbsolute() ? "is absolute path\n" :
"is not absolute path\n" ) + "Last modified: " +
name.lastModified() + "\nLength: " + name.length() +
"\nPath: " + name.getPath() + "\nAbsolute path: " +
name.getAbsolutePath() + "\nParent: " + name.getParent() );
Line 41
create a new File
and assign it to name
Body of if outputs
information about the
file if it exists
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// output information if name is a file
if ( name.isFile() ) {
// append contents of file to outputArea
try {
BufferedReader input = new BufferedReader(
new FileReader( name ) );
StringBuffer buffer = new StringBuffer();
String text;
outputArea.append( "\n\n" );
while ( ( text = input.readLine() ) != null )
buffer.append( text + "\n" );
outputArea.append( buffer.toString() );
}
Outline
Test if our object is a
FileTest.java
file
Line 53
Create reader to gather
data from the file
Lines 57-58
Lines 63-64
Read text until there is
no more in the file
// process file processing problems
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "FILE ERROR",
"FILE ERROR", JOptionPane.ERROR_MESSAGE );
}
} // end if
 2003 Prentice Hall, Inc.
All rights reserved.
77
// output directory listing
78
else if ( name.isDirectory() ) {
79
String directory[] = name.list();
80
81
outputArea.append( "\n\nDirectory contents:\n");
82
83
for ( int i = 0; i < directory.length; i++ )
84
outputArea.append( directory[ i ] + "\n" );
85
}
86
87
} // end outer if
88
89
// not file or directory, output error message
90
else {
91
JOptionPane.showMessageDialog( this,
92
actionEvent.getActionCommand() + " Does Not Exist",
93
"ERROR", JOptionPane.ERROR_MESSAGE );
94
}
95
96
} // end method actionPerformed
97
98
public static void main( String args[] )
99
{
100
FileTest application = new FileTest();
101
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
102
}
103
104 } // end class FileTest
Outline
FileTest.java
Get
a list of the files
in the directory
Line 79
Lines 91-93
If file does not exist,
display error
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
FileTest.java
 2003 Prentice Hall, Inc.
All rights reserved.
17.5 Creating a Sequential-Access File
• Java Files
– Java imposes no structure on a file
– Programmer structures file according to application
– Following program uses simple record structure
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 17.5: BankUI.java
// A reusable GUI for the examples in this chapter.
package com.deitel.jhtp5.ch17;
import java.awt.*;
import javax.swing.*;
public class BankUI extends JPanel {
// label text for GUI
protected final static String names[] = { "Account number",
"First name", "Last name", "Balance", "Transaction Amount" };
// GUI components; protected for future subclass access
protected JLabel labels[];
protected JTextField fields[];
protected JButton doTask1, doTask2;
protected JPanel innerPanelCenter, innerPanelSouth;
Outline
Compile thisBankUI.java
class in
a package for reuse
Line
Bank
GUI3 for all
examples in this
Line
8
chapter
Line 17
These buttons will
perform actions in
later examples
protected int size; // number of text fields in GUI
// constants representing text fields in GUI
public static final int ACCOUNT = 0, FIRSTNAME = 1, LASTNAME = 2,
BALANCE = 3, TRANSACTION = 4;
 2003 Prentice Hall, Inc.
All rights reserved.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Set up GUI. Constructor argument size determines the number of
// rows of GUI components.
public BankUI( int mySize )
{
size = mySize;
labels = new JLabel[ size ];
fields = new JTextField[ size ];
Outline
BankUI.java
// create labels
for ( int count = 0; count < labels.length; count++ )
labels[ count ] = new JLabel( names[ count ] );
// create text fields
for ( int count = 0; count < fields.length; count++ )
fields[ count ] = new JTextField();
// create panel to lay out labels and fields
innerPanelCenter = new JPanel();
innerPanelCenter.setLayout( new GridLayout( size, 2 ) );
// attach labels and fields to innerPanelCenter
for ( int count = 0; count < size; count++ ) {
innerPanelCenter.add( labels[ count ] );
innerPanelCenter.add( fields[ count ] );
}
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// create generic buttons; no labels or event handlers
doTask1 = new JButton();
doTask2 = new JButton();
// create panel to lay out buttons and attach buttons
innerPanelSouth = new JPanel();
innerPanelSouth.add( doTask1 );
innerPanelSouth.add( doTask2 );
Outline
BankUI.java
Lines 73 and 79
// set layout of this container and attach panels to it
setLayout( new BorderLayout() );
add( innerPanelCenter, BorderLayout.CENTER );
add( innerPanelSouth, BorderLayout.SOUTH );
validate(); // validate layout
} // end constructor
// return reference to generic task button doTask1
public JButton getDoTask1Button()
{
return doTask1;
}
// return reference to generic task button doTask2
public JButton getDoTask2Button()
{
return doTask2;
}
Return the task
buttons
 2003 Prentice Hall, Inc.
All rights reserved.
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// return reference to fields array of JTextFields
public JTextField[] getFields()
{
return fields;
}
Outline
BankUI.java
// clear content of text fields
public void clearFields()
{
for ( int count = 0; count < size; count++ )
fields[ count ].setText( "" );
}
// set text field values; throw IllegalArgumentException if
// incorrect number of Strings in argument
public void setFieldValues( String strings[] )
throws IllegalArgumentException
{
if ( strings.length != size )
throw new IllegalArgumentException( "There must be " +
size + " Strings in the array" );
for ( int count = 0; count < size; count++ )
fields[ count ].setText( strings[ count ] );
}
 2003 Prentice Hall, Inc.
All rights reserved.
107
108
// get array of Strings with current text field contents
109
public String[] getFieldValues()
110
{
111
String values[] = new String[ size ];
112
113
for ( int count = 0; count < size; count++ )
114
values[ count ] = fields[ count ].getText();
115
116
return values;
117
}
118
119 } // end class BankUI
Outline
BankUI.java
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 17.6: AccountRecord.java
// A class that represents one record of information.
package com.deitel.jhtp5.ch17;
import java.io.Serializable;
public class AccountRecord implements Serializable {
private int account;
private String firstName;
private String lastName;
private double balance;
Outline
Compile this class in
a package for reuse
AccountRecord.j
ava
Implements
Serializable
Line
3
so AccountRecords can be
used with
input
Line
7 and output
streams
// no-argument constructor calls other constructor with default values
public AccountRecord()
{
this( 0, "", "", 0.0 );
}
// initialize a record
public AccountRecord( int acct, String first, String last, double bal )
{
setAccount( acct );
setFirstName( first );
setLastName( last );
setBalance( bal );
}
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// set account number
public void setAccount( int acct )
{
account = acct;
}
Outline
AccountRecord.j
ava
// get account number
public int getAccount()
{
return account;
}
// set first name
public void setFirstName( String first )
{
firstName = first;
}
// get first name
public String getFirstName()
{
return firstName;
}
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// set last name
public void setLastName( String last )
{
lastName = last;
}
Outline
AccountRecord.j
ava
// get last name
public String getLastName()
{
return lastName;
}
// set balance
public void setBalance( double bal )
{
balance = bal;
}
// get balance
public double getBalance()
{
return balance;
}
} // end class AccountRecord
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 17.7: CreateSequentialFile.java
// Writing objects sequentially to a file with class ObjectOutputStream.
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.deitel.jhtp5.ch17.BankUI;
import com.deitel.jhtp5.ch17.AccountRecord;
public class CreateSequentialFile extends JFrame {
private ObjectOutputStream output;
private BankUI userInterface;
private JButton enterButton, openButton;
Outline
CreateSequentia
Import
our GUI class
lFile.java
and record class
Lines 8-9
Lines 22 and 26
// set up GUI
public CreateSequentialFile()
{
super( "Creating a Sequential File of Objects" );
// create instance of reusable user interface
userInterface = new BankUI( 4 ); // four textfields
getContentPane().add( userInterface, BorderLayout.CENTER );
// configure button doTask1 for use in this program
openButton = userInterface.getDoTask1Button();
openButton.setText( "Save into File ..." );
Create our interface
and get a reference to
the first task button
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// register listener to call openFile when button pressed
openButton.addActionListener(
// anonymous inner class to handle openButton event
new ActionListener() {
// call openFile when button pressed
public void actionPerformed( ActionEvent event )
{
openFile();
}
Outline
CreateSequentia
lFile.java
Line 46
} // end anonymous inner class
); // end call to addActionListener
// configure button doTask2 for use in this program
enterButton = userInterface.getDoTask2Button();
enterButton.setText( "Enter" );
enterButton.setEnabled( false ); // disable button
Get a reference to the
second task button
// register listener to call addRecord when button pressed
enterButton.addActionListener(
 2003 Prentice Hall, Inc.
All rights reserved.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// anonymous inner class to handle enterButton event
new ActionListener() {
// call addRecord when button pressed
public void actionPerformed( ActionEvent event )
{
addRecord();
}
Outline
CreateSequentia
lFile.java
} // end anonymous inner class
); // end call to addActionListener
// register window listener to handle window closing event
addWindowListener(
// anonymous inner class to handle windowClosing event
new WindowAdapter() {
// add current record in GUI to file, then close file
public void windowClosing( WindowEvent event )
{
if ( output != null )
addRecord();
closeFile();
}
 2003 Prentice Hall, Inc.
All rights reserved.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
} // end anonymous inner class
); // end call to addWindowListener
setSize( 300, 200 );
setVisible( true );
} // end CreateSequentialFile constructor
// allow user to specify file name
Constant
private void openFile()
only
{
// display file dialog, so user can choose file to open
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
int result = fileChooser.showSaveDialog( this );
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
Outline
CreateSequentia
Instantiate a
lFile.java
JFileChooser
and assign it to
Line 94
fileChooser
Line 95
FILES_ONLY indicates
Linebe97selected
files can
Lines 100-101
LineMethod
103
showSaveDialog
causes the
JFileChooser
titled Save to appear
File fileName = fileChooser.getSelectedFile(); // get selected file
Return if user clicked
Cancel button on
dialog
Retrieve selected file
 2003 Prentice Hall, Inc.
All rights reserved.
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// display error if invalid
if ( fileName == null || fileName.getName().equals( "" ) )
JOptionPane.showMessageDialog( this, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
else {
// open file
try {
output = new ObjectOutputStream(
new FileOutputStream( fileName ) );
Outline
CreateSequentia
lFile.java
Open selected file
openButton.setEnabled( false );
enterButton.setEnabled( true );
}
// process exceptions from opening file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error Opening File",
"Error", JOptionPane.ERROR_MESSAGE );
}
} // end else
} // end method openFile
 2003 Prentice Hall, Inc.
All rights reserved.
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// close file and terminate application
private void closeFile()
{
// close file
try {
output.close();
System.exit( 0 );
}
// process exceptions from closing file
catch( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error closing file",
"Error", JOptionPane.ERROR_MESSAGE );
System.exit( 1 );
}
Outline
Method closeFile
closes the current file
CreateSequentia
lFile.java
Line 132
Line 154
} // end method closeFile
// add record to file
public void addRecord()
{
int accountNumber = 0;
AccountRecord record;
String fieldValues[] = userInterface.getFieldValues();
Get the data in the
textfields
 2003 Prentice Hall, Inc.
All rights reserved.
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
Outline
// if account field value is not empty
if ( ! fieldValues[ BankUI.ACCOUNT ].equals( "" ) ) {
// output values to file
try {
accountNumber = Integer.parseInt(
fieldValues[ BankUI.ACCOUNT ] );
CreateSequentia
lFile.java
Lines 167-170
if ( accountNumber > 0 ) {
// create new record
record = new AccountRecord( accountNumber,
fieldValues[ BankUI.FIRSTNAME ],
fieldValues[ BankUI.LASTNAME ],
Double.parseDouble( fieldValues[ BankUI.BALANCE ] ) );
// output record and flush buffer
output.writeObject( record );
output.flush();
Lines 173-174
Create a new record
Write the record to the file
immediately
}
else {
JOptionPane.showMessageDialog( this,
"Account number must be greater than 0",
"Bad account number", JOptionPane.ERROR_MESSAGE );
}
 2003 Prentice Hall, Inc.
All rights reserved.
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// clear textfields
userInterface.clearFields();
} // end try
// process invalid account number or balance format
catch ( NumberFormatException formatException ) {
JOptionPane.showMessageDialog( this,
"Bad account number or balance", "Invalid Number Format",
JOptionPane.ERROR_MESSAGE );
}
Outline
CreateSequentia
lFile.java
// process exceptions from file output
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error writing to file",
"IO Exception", JOptionPane.ERROR_MESSAGE );
closeFile();
}
} // end if
} // end method addRecord
 2003 Prentice Hall, Inc.
All rights reserved.
206
public static void main( String args[] )
207
{
208
new CreateSequentialFile();
209
}
210
211 } // end class CreateSequentialFile
Outline
CreateSequentia
lFile.java
BankUI graphical user
interface
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
CreateSequentia
lFile.java
Select location
for file here
Files and
directories are
displayed here
Click Save to
submit new
file name to
program
 2003 Prentice Hall, Inc.
All rights reserved.
17.6 Reading Data from a SequentialAccess File
• Data stored in files
– Retrieved for processing when needed
– Accessing a sequential file
• Data must be read in same format it was written
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.8 Sample data for the program of
Fig. 17.7
Sample Data
100
Bob
Jones
24.98
200
Steve
Doe
-345.67
300
Pam
White
0.00
400
Sam
Stone
-42.16
500
Sue
Rich
224.62
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 17.9: ReadSequentialFile.java
// This program reads a file of objects sequentially
// and displays each record.
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Outline
ReadSequentialF
ile.java
Line 22
import com.deitel.jhtp5.ch17.*;
public class ReadSequentialFile extends JFrame {
private ObjectInputStream input;
private BankUI userInterface;
private JButton nextButton, openButton;
// Constructor -- initialize the Frame
public ReadSequentialFile()
{
super( "Reading a Sequential File of Objects" );
// create instance of reusable user interface
userInterface = new BankUI( 4 ); // four textfields
getContentPane().add( userInterface, BorderLayout.CENTER );
Create user interface
 2003 Prentice Hall, Inc.
All rights reserved.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// get reference to generic task button doTask1 from BankUI
openButton = userInterface.getDoTask1Button();
openButton.setText( "Open File" );
// register listener to call openFile when button pressed
openButton.addActionListener(
// anonymous inner class to handle openButton event
new ActionListener() {
Outline
Get a reference to the
ReadSequentialF
first task button
ile.java
Line 27
// close file and terminate application
public void actionPerformed( ActionEvent event )
{
openFile();
}
} // end anonymous inner class
); // end call to addActionListener
// register window listener for window closing event
addWindowListener(
// anonymous inner class to handle windowClosing event
new WindowAdapter() {
 2003 Prentice Hall, Inc.
All rights reserved.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// close file and terminate application
public void windowClosing( WindowEvent event )
{
if ( input != null )
closeFile();
Outline
ReadSequentialF
ile.java
System.exit( 0 );
}
Line 65
} // end anonymous inner class
); // end call to addWindowListener
// get reference to generic task button doTask2 from BankUI
nextButton = userInterface.getDoTask2Button();
nextButton.setText( "Next Record" );
nextButton.setEnabled( false );
Get a reference to the
second task button
// register listener to call readRecord when button pressed
nextButton.addActionListener(
// anonymous inner class to handle nextRecord event
new ActionListener() {
 2003 Prentice Hall, Inc.
All rights reserved.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Outline
// call readRecord when user clicks nextRecord
public void actionPerformed( ActionEvent event )
{
readRecord();
}
ReadSequentialF
ile.java
} // end anonymous inner class
Line 95
); // end call to addActionListener
Line
96
Instantiate
a
JFileChooser
Lineassign
98 it to
and
fileChooser
pack();
setSize( 300, 200 );
setVisible( true );
} // end ReadSequentialFile constructor
// enable user to select file to open
Constant
private void openFile()
{
only
// display file dialog so user can select file to open
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
FILES_ONLY indicates
files can be selected
int result = fileChooser.showOpenDialog( this );
Method showOpenDialog
causes the JFileChooser
titled Open to appear
 2003 Prentice Hall, Inc.
All rights reserved.
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
// obtain selected file
File fileName = fileChooser.getSelectedFile();
// display error if file name invalid
if ( fileName == null || fileName.getName().equals( "" ) )
JOptionPane.showMessageDialog( this, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
else {
// open file
try {
input = new ObjectInputStream(
new FileInputStream( fileName ) );
Outline
ReadSequentialF
ile.java
Return if user clicked
Cancel
button on
Line 101-102
dialog
Line 105
Retrieve selected file
Lines 116-117
Open selected file
openButton.setEnabled( false );
nextButton.setEnabled( true );
}
// process exceptions opening file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error Opening File",
"Error", JOptionPane.ERROR_MESSAGE );
}
 2003 Prentice Hall, Inc.
All rights reserved.
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
} // end else
} // end method openFile
// read record from file
public void readRecord()
{
AccountRecord record;
// input the values from the file
try {
record = ( AccountRecord ) input.readObject();
// create array of Strings to display in GUI
String values[] = { String.valueOf( record.getAccount() ),
record.getFirstName(), record.getLastName(),
String.valueOf( record.getBalance() ) };
Outline
ReadSequentialF
ile.java
Line 140
Method readObject
reads an Object from the
ObjectInputStream
// display record contents
userInterface.setFieldValues( values );
}
// display message when end-of-file reached
catch ( EOFException endOfFileException ) {
nextButton.setEnabled( false );
 2003 Prentice Hall, Inc.
All rights reserved.
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
JOptionPane.showMessageDialog( this, "No more records in file",
"End of File", JOptionPane.ERROR_MESSAGE );
Outline
}
// display error message if class is not found
catch ( ClassNotFoundException classNotFoundException ) {
JOptionPane.showMessageDialog( this, "Unable to create object",
"Class Not Found", JOptionPane.ERROR_MESSAGE );
}
ReadSequentialF
ile.java
Line 175
// display error message if cannot read due to problem with file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this,
"Error during read from file",
"Read Error", JOptionPane.ERROR_MESSAGE );
}
} // end method readRecord
// close file and terminate application
private void closeFile()
{
// close file and exit
try {
input.close();
System.exit( 0 );
}
Method closeFile
closes the current file
 2003 Prentice Hall, Inc.
All rights reserved.
182
183
// process exception while closing file
184
catch ( IOException ioException ) {
185
JOptionPane.showMessageDialog( this, "Error closing file",
186
"Error", JOptionPane.ERROR_MESSAGE );
187
188
System.exit( 1 );
189
}
190
191
} // end method closeFile
192
193
public static void main( String args[] )
194
{
195
new ReadSequentialFile();
196
}
197
198 } // end class ReadSequentialFile
Outline
ReadSequentialF
ile.java
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
ReadSequentialF
ile.java
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 17.10: CreditInquiry.java
// This program reads a file sequentially and displays the contents in a
// text area based on the type of account the user requests
// (credit balance, debit balance or zero balance).
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;
Outline
CreditInquiry.j
ava
import com.deitel.jhtp5.ch17.AccountRecord;
public class CreditInquiry extends JFrame {
private JTextArea recordDisplayArea;
private JButton openButton, creditButton, debitButton, zeroButton;
private JPanel buttonPanel;
private
private
private
private
ObjectInputStream input;
FileInputStream fileInput;
File fileName;
String accountType;
static private DecimalFormat twoDigits = new DecimalFormat( "0.00" );
// set up GUI
public CreditInquiry()
{
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
super( "Credit Inquiry Program" );
Outline
Container container = getContentPane();
buttonPanel = new JPanel(); // set up panel for buttons
CreditInquiry.j
ava
// create and configure button to open file
openButton = new JButton( "Open File" );
buttonPanel.add( openButton );
// register openButton listener
openButton.addActionListener(
// anonymous inner class to handle openButton event
new ActionListener() {
// open file for processing
public void actionPerformed( ActionEvent event )
{
openFile();
}
} // end anonymous inner class
); // end call to addActionListener
 2003 Prentice Hall, Inc.
All rights reserved.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// create and configure button to get accounts with credit balances
creditButton = new JButton( "Credit balances" );
buttonPanel.add( creditButton );
creditButton.addActionListener( new ButtonHandler() );
Outline
CreditInquiry.j
ava
// create and configure button to get accounts with debit balances
debitButton = new JButton( "Debit balances" );
buttonPanel.add( debitButton );
debitButton.addActionListener( new ButtonHandler() );
// create and configure button to get accounts with zero balances
zeroButton = new JButton( "Zero balances" );
buttonPanel.add( zeroButton );
zeroButton.addActionListener( new ButtonHandler() );
// set up display area
recordDisplayArea = new JTextArea();
JScrollPane scroller = new JScrollPane( recordDisplayArea );
// attach components to content pane
container.add( scroller, BorderLayout.CENTER );
container.add( buttonPanel, BorderLayout.SOUTH );
 2003 Prentice Hall, Inc.
All rights reserved.
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
creditButton.setEnabled( false ); // disable creditButton
debitButton.setEnabled( false ); // disable debitButton
zeroButton.setEnabled( false );
// disable zeroButton
// register window listener
addWindowListener(
Outline
CreditInquiry.j
ava
// anonymous inner class for windowClosing event
new WindowAdapter() {
// close file and terminate program
public void windowClosing( WindowEvent event )
{
closeFile();
System.exit( 0 );
}
} // end anonymous inner class
); // end call to addWindowListener
pack(); // pack components and display window
setSize( 600, 250 );
setVisible( true );
} // end CreditInquiry constructor
 2003 Prentice Hall, Inc.
All rights reserved.
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// enable user to choose file to open
private void openFile()
{
// display dialog, so user can choose file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
Outline
CreditInquiry.j
ava
int result = fileChooser.showOpenDialog( this );
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
fileName = fileChooser.getSelectedFile(); // obtain selected file
// display error if file name invalid
if ( fileName == null || fileName.getName().equals( "" ) )
JOptionPane.showMessageDialog( this, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
// open file
try {
// close file from previous operation
if ( input != null )
input.close();
 2003 Prentice Hall, Inc.
All rights reserved.
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
fileInput = new FileInputStream( fileName );
input = new ObjectInputStream( fileInput );
openButton.setEnabled( false );
creditButton.setEnabled( true );
debitButton.setEnabled( true );
zeroButton.setEnabled( true );
Outline
CreditInquiry.j
ava
}
// catch problems manipulating file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "File does not exist",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
}
} // end method openFile
// close file before application terminates
private void closeFile()
{
// close file
try {
if ( input != null )
input.close();
}
 2003 Prentice Hall, Inc.
All rights reserved.
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
Outline
// process exception from closing file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error closing file",
"Error", JOptionPane.ERROR_MESSAGE );
CreditInquiry.j
ava
System.exit( 1 );
}
Lines 177-178
} // end method closeFile
// read records from file and display only records of appropriate type
private void readRecords()
{
AccountRecord record;
// read records
try {
if ( input != null )
input.close();
fileInput = new FileInputStream( fileName );
input = new ObjectInputStream( fileInput );
Create a stream from
which to read the records
recordDisplayArea.setText( "The accounts are:\n" );
 2003 Prentice Hall, Inc.
All rights reserved.
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
Outline
// input the values from the file
while ( true ) {
// read one AccountRecord
record = ( AccountRecord ) input.readObject();
Method CreditInquiry.j
readObject
reads an Object
from the
ava
ObjectInputStream
// if proper acount type, display record
if ( shouldDisplay( record.getBalance() ) )
recordDisplayArea.append( record.getAccount() + "\t" +
record.getFirstName() + "\t" + record.getLastName() +
"\t" + twoDigits.format( record.getBalance() ) + "\n" );
Line 186
Line 198
}
} // end try
// close file when end-of-file reached
catch ( EOFException eofException ) {
closeFile();
}
An EOFException is
thrown when the end of the
file is reached
// display error if cannot read object because class not found
catch ( ClassNotFoundException classNotFound ) {
JOptionPane.showMessageDialog( this, "Unable to create object",
"Class Not Found", JOptionPane.ERROR_MESSAGE );
}
 2003 Prentice Hall, Inc.
All rights reserved.
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// display error if cannot read because problem with file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error reading from file",
"Error", JOptionPane.ERROR_MESSAGE );
}
Outline
CreditInquiry.j
ava
} // end method readRecords
// use record type to determine if record should be displayed
private boolean shouldDisplay( double balance )
{
if ( accountType.equals( "Credit balances" ) && balance < 0 )
return true;
else if ( accountType.equals( "Debit balances" ) && balance > 0 )
return true;
else if ( accountType.equals( "Zero balances" ) && balance == 0 )
return true;
return false;
}
 2003 Prentice Hall, Inc.
All rights reserved.
231
public static void main( String args[] )
232
{
233
new CreditInquiry();
234
}
235
236
// class for creditButton, debitButton and zeroButton event handling
237
private class ButtonHandler implements ActionListener {
238
239
// read records from file
240
public void actionPerformed( ActionEvent event )
241
{
242
accountType = event.getActionCommand();
243
readRecords();
244
}
245
246
} // end class ButtonHandler
247
248 } // end class CreditInquiry
Outline
CreditInquiry.j
ava
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
CreditInquiry.j
ava
 2003 Prentice Hall, Inc.
All rights reserved.
17.7 Updating Sequential-Access Files
• Difficult to update a sequential-access file
– Entire file must be rewritten to change one field
– Only acceptable if many records being updated at once
 2003 Prentice Hall, Inc. All rights reserved.
17.8 Random-Access Files
• “Instant-access” applications
– Record must be located immediately
– Transaction-processing systems require rapid access
• Random-access files
– Access individual records directly and quickly
– Use fixed length for every record
• Easy to calculate record locations
– Insert records without destroying other data in file
– Fig. 16.10 shows random-access file
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.11 Java’s view of a random-access file
0
100
200
300
400
500
byte offsets
100
bytes
100
bytes
 2003 Prentice Hall, Inc. All rights reserved.
100
bytes
100
bytes
100
bytes
100
bytes
17.9 Creating a Random-Access File
• RandomAccessFile objects
– Like DataInputStream and DataOutputstream
– Reads or writes data in spot specified by file-position pointer
• Manipulates all data as primitive types
• Normally writes one object at a time to file
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Fig. 17.12: RandomAccessAccountRecord.java
// Subclass of AccountRecord for random access file programs.
package com.deitel.jhtp5.ch17;
import java.io.*;
Outline
Class extends
AccountRecord
RandomAccessAcc
ountRecord.java
public class RandomAccessAccountRecord extends AccountRecord {
Line 7
public static final int SIZE = 72;
// bytes in one record
// no-argument constructor calls other constructor with default values
public RandomAccessAccountRecord()
{
this( 0, "", "", 0.0 );
}
// initialize a RandomAccessAccountRecord
public RandomAccessAccountRecord( int account, String firstName,
String lastName, double balance )
{
super( account, firstName, lastName, balance );
}
 2003 Prentice Hall, Inc.
All rights reserved.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// read a record from specified RandomAccessFile
public void read( RandomAccessFile file ) throws IOException
{
setAccount( file.readInt() );
setFirstName( readName( file ) );
setLastName( readName( file ) );
setBalance( file.readDouble() );
}
// ensure that name is proper length
private String readName( RandomAccessFile file ) throws IOException
{
char name[] = new char[ 15 ], temp;
for ( int count = 0; count < name.length; count++ ) {
temp = file.readChar();
name[ count ] = temp;
}
Outline
Method
read reads one
RandomAccessAcc
record
from the
ountRecord.java
RandomAccessFile
Line 25
Method readInt
Lineone
27 integer
reads
Method
readDouble
Line
30
reads one double
39
MethodLine
readChar
reads one character
return new String( name ).replace( '\0', ' ' );
}
 2003 Prentice Hall, Inc.
All rights reserved.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// write a record to specified RandomAccessFile
public void write( RandomAccessFile file ) throws IOException
{
file.writeInt( getAccount() );
writeName( file, getFirstName() );
writeName( file, getLastName() );
file.writeDouble( getBalance() );
}
// write a name to file; maximum of 15 characters
private void writeName( RandomAccessFile file, String name )
throws IOException
{
StringBuffer buffer = null;
if ( name != null )
buffer = new StringBuffer( name );
else
buffer = new StringBuffer( 15 );
buffer.setLength( 15 );
file.writeChars( buffer.toString() );
}
Outline
Method write writes
RandomAccessAcc
one
record to the
ountRecord.java
RandomAccessFile
Line 47
Method writeInt
writes one integer
Line 49
Method writeDouble
Line 52
writes one double
Line
56
Method
writeName
writes a string to the file
Line 67
Method writeChars
writes a string
} // end class RandomAccessAccountRecord
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Fig. 17.13: CreateRandomFile.java
// Creates random access file by writing 100 empty records to disk.
import java.io.*;
import javax.swing.*;
import com.deitel.jhtp5.ch17.RandomAccessAccountRecord;
Outline
CreateRandomFil
e.java
public class CreateRandomFile {
private static final int NUMBER_RECORDS = 100;
// enable user to select file to open
private void createFile()
{
// display dialog so user can choose file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
int result = fileChooser.showSaveDialog( null );
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
// obtain selected file
File fileName = fileChooser.getSelectedFile();
 2003 Prentice Hall, Inc.
All rights reserved.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// display error if file name invalid
if ( fileName == null || fileName.getName().equals( "" ) )
JOptionPane.showMessageDialog( null, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
Outline
CreateRandomFil
e.java
else {
Lines 37-38
// open file
try {
RandomAccessFile file =
new RandomAccessFile( fileName, "rw" );
Line 45
Open a
RandomAccessFile
RandomAccessAccountRecord blankRecord =
new RandomAccessAccountRecord();
// write 100 blank records
for ( int count = 0; count < NUMBER_RECORDS; count++ )
blankRecord.write( file );
Write 100 blank records
file.close(); // close file
// display message that file was created
JOptionPane.showMessageDialog( null, "Created file " +
fileName, "Status", JOptionPane.INFORMATION_MESSAGE );
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
System.exit( 0 );
// terminate program
} // end try
// process exceptions during open, write or close file operations
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( null, "Error processing file",
"Error processing file", JOptionPane.ERROR_MESSAGE );
Outline
CreateRandomFil
e.java
System.exit( 1 );
}
} // end else
} // end method createFile
public static void main( String args[] )
{
CreateRandomFile application = new CreateRandomFile();
application.createFile();
}
} // end class CreateRandomFile
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
CreateRandomFil
e.java
 2003 Prentice Hall, Inc.
All rights reserved.
17.10 Writing Data Randomly to a RandomAccess File
• RandomAccessFile method seek
– Determines location in file where record is stored
– Sets file-position pointer to a specific point in file
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Fig. 17.14: WriteRandomFile.java
// This program uses textfields to get information from the user at the
// keyboard and writes the information to a random-access file.
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
Outline
WriteRandomFile
.java
import com.deitel.jhtp5.ch17.*;
public class WriteRandomFile extends JFrame {
private RandomAccessFile output;
private BankUI userInterface;
private JButton enterButton, openButton;
private static final int NUMBER_RECORDS = 100;
// set up GUI
public WriteRandomFile()
{
super( "Write to random access file" );
// create instance of reusable user interface BankUI
userInterface = new BankUI( 4 ); // four textfields
getContentPane().add( userInterface,
BorderLayout.CENTER );
 2003 Prentice Hall, Inc.
All rights reserved.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// get reference to generic task button doTask1 in BankUI
openButton = userInterface.getDoTask1Button();
openButton.setText( "Open..." );
// register listener to call openFile when button pressed
openButton.addActionListener(
Outline
WriteRandomFile
.java
// anonymous inner class to handle openButton event
new ActionListener() {
// allow user to select file to open
public void actionPerformed( ActionEvent event )
{
openFile();
}
} // end anonymous inner class
); // end call to addActionListener
// register window listener for window closing event
addWindowListener(
 2003 Prentice Hall, Inc.
All rights reserved.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// anonymous inner class to handle windowClosing event
new WindowAdapter() {
// add record in GUI, then close file
public void windowClosing( WindowEvent event )
{
if ( output != null )
addRecord();
Outline
WriteRandomFile
.java
closeFile();
}
} // end anonymous inner class
); // end call to addWindowListener
// get reference to generic task button doTask2 in BankUI
enterButton = userInterface.getDoTask2Button();
enterButton.setText( "Enter" );
enterButton.setEnabled( false );
// register listener to call addRecord when button pressed
enterButton.addActionListener(
 2003 Prentice Hall, Inc.
All rights reserved.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// anonymous inner class to handle enterButton event
new ActionListener() {
// add record to file
public void actionPerformed( ActionEvent event )
{
addRecord();
}
Outline
WriteRandomFile
.java
} // end anonymous inner class
); // end call to addActionListener
setSize( 300, 150 );
setVisible( true );
}
// enable user to choose file to open
private void openFile()
{
// display file dialog so user can select file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
int result = fileChooser.showOpenDialog( this );
 2003 Prentice Hall, Inc.
All rights reserved.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
// obtain selected file
File fileName = fileChooser.getSelectedFile();
// display error if file name invalid
if ( fileName == null || fileName.getName().equals( "" ) )
JOptionPane.showMessageDialog( this, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
Outline
WriteRandomFile
.java
Line 117
else {
// open file
try {
output = new RandomAccessFile( fileName, "rw" );
enterButton.setEnabled( true );
openButton.setEnabled( false );
}
Open a
RandomAccessFile
// process exception while opening file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "File does not exist",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
}
 2003 Prentice Hall, Inc.
All rights reserved.
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
} // end else
} // end method openFile
// close file and terminate application
private void closeFile()
{
// close file and exit
try {
if ( output != null )
output.close();
Outline
WriteRandomFile
.java
System.exit( 0 );
}
// process exception while closing file
catch( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error closing file",
"Error", JOptionPane.ERROR_MESSAGE );
System.exit( 1 );
}
} // end method closeFile
 2003 Prentice Hall, Inc.
All rights reserved.
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
Outline
// add one record to file
private void addRecord()
{
String fields[] = userInterface.getFieldValues();
WriteRandomFile
.java
// ensure account field has a value
if ( ! fields[ BankUI.ACCOUNT ].equals( "" ) ) {
Lines 176-177
// output values to file
try {
int accountNumber =
Integer.parseInt( fields[ ACCOUNT ] );
if ( accountNumber > 0 && accountNumber <= NUMBER_RECORDS ) {
RandomAccessAccountRecord record
new RandomAccessAccountRecord();
record.setAccount( accountNumber );
record.setFirstName( fields[ BankUI.FIRSTNAME ] );
record.setLastName( fields[ BankUI.LASTNAME ] );
record.setBalance( Double.parseDouble(
fields[ BankUI.BALANCE ] ) );
output.seek( ( accountNumber - 1 ) *
RandomAccessAccountRecord.SIZE );
record.write( output );
Set the file pointer to the
appropriate place
}
 2003 Prentice Hall, Inc.
All rights reserved.
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
else {
JOptionPane.showMessageDialog( this,
"Account must be between 1 and 100",
"Invalid account number", JOptionPane.ERROR_MESSAGE );
}
userInterface.clearFields();
Outline
WriteRandomFile
.java
// clear TextFields
} // end try
// process improper account number or balance format
catch ( NumberFormatException formatException ) {
JOptionPane.showMessageDialog( this,
"Bad account number or balance",
"Invalid Number Format", JOptionPane.ERROR_MESSAGE );
}
// process exceptions while writing to file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this,
"Error writing to the file", "IO Exception",
JOptionPane.ERROR_MESSAGE );
closeFile();
}
 2003 Prentice Hall, Inc.
All rights reserved.
205
206
} // end if
207
208
} // end method addRecord
209
210
public static void main( String args[] )
211
{
212
new WriteRandomFile();
213
}
214
215 } // end class WriteRandomFile
Outline
WriteRandomFile
.java
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
WriteRandomFile
.java
 2003 Prentice Hall, Inc.
All rights reserved.
17.11 Reading Data Sequentially from a
Random-Access File
• Read all valid records in a RandomAccessFile
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Fig. 17.15: ReadRandomFile.java
// This program reads a random-access file sequentially and
// displays the contents one record at a time in text fields.
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.text.DecimalFormat;
import javax.swing.*;
Outline
ReadRandomFile.
java
import com.deitel.jhtp5.ch17.*;
public class ReadRandomFile extends JFrame {
private BankUI userInterface;
private RandomAccessFile input;
private JButton nextButton, openButton;
private static DecimalFormat twoDigits = new DecimalFormat( "0.00" );
// set up GUI
public ReadRandomFile()
{
super( "Read Client File" );
// create reusable user interface instance
userInterface = new BankUI( 4 ); // four textfields
getContentPane().add( userInterface );
 2003 Prentice Hall, Inc.
All rights reserved.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// configure generic doTask1 button from BankUI
openButton = userInterface.getDoTask1Button();
openButton.setText( "Open File for Reading..." );
// register listener to call openFile when button pressed
openButton.addActionListener(
Outline
ReadRandomFile.
java
// anonymous inner class to handle openButton event
new ActionListener() {
// enable user to select file to open
public void actionPerformed( ActionEvent event )
{
openFile();
}
} // end anonymous inner class
); // end call to addActionListener
// configure generic doTask2 button from BankUI
nextButton = userInterface.getDoTask2Button();
nextButton.setText( "Next" );
nextButton.setEnabled( false );
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// register listener to call readRecord when button pressed
nextButton.addActionListener(
// anonymous inner class to handle nextButton event
new ActionListener() {
Outline
ReadRandomFile.
java
// read a record when user clicks nextButton
public void actionPerformed( ActionEvent event )
{
readRecord();
}
} // end anonymous inner class
); // end call to addActionListener
// register listener for window closing event
addWindowListener(
// anonymous inner class to handle windowClosing event
new WindowAdapter() {
 2003 Prentice Hall, Inc.
All rights reserved.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// close file and terminate application
public void windowClosing( WindowEvent event )
{
closeFile();
}
Outline
ReadRandomFile.
java
} // end anonymous inner class
); // end call to addWindowListener
setSize( 300, 150 );
setVisible( true );
} // end constructor
// enable user to select file to open
private void openFile()
{
// display file dialog so user can select file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
int result = fileChooser.showOpenDialog( this );
 2003 Prentice Hall, Inc.
All rights reserved.
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
// obtain selected file
File fileName = fileChooser.getSelectedFile();
// display error is file name invalid
if ( fileName == null || fileName.getName().equals( "" ) )
JOptionPane.showMessageDialog( this, "Invalid File Name",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
Outline
ReadRandomFile.
java
Line 115
else {
// open file
try {
input = new RandomAccessFile( fileName, "r" );
nextButton.setEnabled( true );
openButton.setEnabled( false );
}
Open a
RandomAccessFile
// catch exception while opening file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "File does not exist",
"Invalid File Name", JOptionPane.ERROR_MESSAGE );
}
 2003 Prentice Hall, Inc.
All rights reserved.
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Outline
} // end else
} // end method openFile
// read one record
private void readRecord()
{
RandomAccessAccountRecord record = new RandomAccessAccountRecord();
ReadRandomFile.
java
Line 139
// read a record and display
try {
do {
record.read( input );
} while ( record.getAccount() == 0 );
Read until a valid
record is found
String values[] = { String.valueOf( record.getAccount() ),
record.getFirstName(), record.getLastName(),
String.valueOf( record.getBalance() ) };
userInterface.setFieldValues( values );
}
 2003 Prentice Hall, Inc.
All rights reserved.
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// close file when end-of-file reached
catch ( EOFException eofException ) {
JOptionPane.showMessageDialog( this, "No more records",
"End-of-file reached", JOptionPane.INFORMATION_MESSAGE );
closeFile();
}
// process exceptions from problem with file
catch ( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error Reading File",
"Error", JOptionPane.ERROR_MESSAGE );
Outline
ReadRandomFile.
java
If the end-of-file marker
is reached, there are no
Line 149
more records
System.exit( 1 );
}
} // end method readRecord
// close file and terminate application
private void closeFile()
{
// close file and exit
try {
if ( input != null )
input.close();
System.exit( 0 );
}
 2003 Prentice Hall, Inc.
All rights reserved.
175
176
// process exception closing file
177
catch( IOException ioException ) {
178
JOptionPane.showMessageDialog( this, "Error closing file",
179
"Error", JOptionPane.ERROR_MESSAGE );
180
181
System.exit( 1 );
182
}
183
184
} // end method closeFile
185
186
public static void main( String args[] )
187
{
188
new ReadRandomFile();
189
}
190
191 } // end class ReadRandomFile
Outline
ReadRandomFile.
java
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
ReadRandomFile.
java
 2003 Prentice Hall, Inc.
All rights reserved.
17.12 Case Study: A TransactionProcessing Program
• Substantial transaction-processing system
– Uses random-access file
– Updates, adds and deletes accounts
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.16 Transaction Processor window
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.17 Update Record: Loading a record to
update
Type account number and press
the Enter key to load record.
Action button has a different
label depending on the
operation to perform.
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.18 Update Record: Inputting a
transaction
Updated balance after user
pressed Update.
Enter transaction amount.
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.19 New Record: Adding a record to the
file
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 17.20 Delete Record: Removing a record
from the file
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 17.21: TransactionProcessor.java
// A transaction processing program using random-access files.
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.text.DecimalFormat;
import javax.swing.*;
Outline
TransactionProc
essor.java
import com.deitel.jhtp5.ch17.*;
public class TransactionProcessor extends JFrame {
private
private
private
private
private
private
private
BankUI userInterface;
JMenuItem newItem, updateItem, deleteItem, openItem, exitItem;
JTextField fields[];
JTextField accountField, transactionField;
JButton actionButton, cancelButton;
FileEditor dataFile;
RandomAccessAccountRecord record;
public TransactionProcessor()
{
super( "Transaction Processor" );
 2003 Prentice Hall, Inc.
All rights reserved.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// set up desktop, menu bar and File menu
userInterface = new BankUI( 5 );
getContentPane().add( userInterface );
userInterface.setVisible( false );
// set up the action button
actionButton = userInterface.getDoTask1Button();
actionButton.setText( "Save Changes" );
actionButton.setEnabled( false );
Outline
TransactionProc
essor.java
// register action button listener
actionButton.addActionListener(
new ActionListener() { // anonymous inner class
public void actionPerformed( ActionEvent event )
{
String action = event.getActionCommand();
performAction( action );
} // end method actionPerformed
} // end anonymous inner class
); // end call to addActionListener
 2003 Prentice Hall, Inc.
All rights reserved.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// set up the cancel button
cancelButton = userInterface.getDoTask2Button();
cancelButton.setText( "Cancel" );
cancelButton.setEnabled( false );
// register cancel button listener
cancelButton.addActionListener(
Outline
TransactionProc
essor.java
new ActionListener() { // anonymous inner class
// clear the fields
public void actionPerformed( ActionEvent event )
{
userInterface.clearFields();
}
} // end anonymous inner class
); // end call to addActionListener
// set up the listener for the account field
fields = userInterface.getFields();
accountField = fields[ BankUI.ACCOUNT ];
accountField.addActionListener(
 2003 Prentice Hall, Inc.
All rights reserved.
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
new ActionListener() { // anonymous inner class
public void actionPerformed( ActionEvent event )
{
displayRecord( "0" );
}
Outline
TransactionProc
essor.java
} // end anonymous inner class
); // end call to addActionListener
// create reference to the transaction field
transactionField = fields[ BankUI.TRANSACTION ];
// register transaction field listener
transactionField.addActionListener(
new ActionListener() { // anonymous inner class
// update the GUI fields
public void actionPerformed( ActionEvent event )
{
displayRecord( transactionField.getText() );
}
} // end anonymous inner class
 2003 Prentice Hall, Inc.
All rights reserved.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
); // end call to addActionListener
JMenuBar menuBar = new JMenuBar(); // set up the menu
setJMenuBar( menuBar );
JMenu fileMenu = new JMenu( "File" );
menuBar.add( fileMenu );
Outline
TransactionProc
essor.java
// set up menu item for adding a record
newItem = new JMenuItem( "New Record" );
newItem.setEnabled( false );
// register new item listener
newItem.addActionListener(
new ActionListener() { // anonymous inner class
public void actionPerformed( ActionEvent event )
{
// set up the GUI fields for editing
fields[ BankUI.ACCOUNT ].setEnabled( true );
fields[ BankUI.FIRSTNAME ].setEnabled( true );
fields[ BankUI.LASTNAME ].setEnabled( true );
fields[ BankUI.BALANCE ].setEnabled( true );
fields[ BankUI.TRANSACTION ].setEnabled( false );
 2003 Prentice Hall, Inc.
All rights reserved.
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
actionButton.setEnabled( true );
actionButton.setText( "Create" );
cancelButton.setEnabled( true );
userInterface.clearFields(); // reset the textfields
Outline
TransactionProc
essor.java
} // end method actionPerformed
} // end anonymous inner class
); // end call to addActionListener
// set up menu item for updating a record
updateItem = new JMenuItem( "Update Record" );
updateItem.setEnabled( false );
// register update item listener
updateItem.addActionListener(
new ActionListener() { // anonymous inner class
public void actionPerformed( ActionEvent event )
{
 2003 Prentice Hall, Inc.
All rights reserved.
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// set up the GUI fields for editing
fields[ BankUI.ACCOUNT ].setEnabled( true );
fields[ BankUI.FIRSTNAME ].setEnabled( false );
fields[ BankUI.LASTNAME ].setEnabled( false );
fields[ BankUI.BALANCE ].setEnabled( false );
fields[ BankUI.TRANSACTION ].setEnabled( true );
Outline
TransactionProc
essor.java
actionButton.setEnabled( true );
actionButton.setText( "Update" );
cancelButton.setEnabled( true );
userInterface.clearFields(); // reset the textfields
} // end method actionPerformed
} // end anonymous inner class
); // end call to addActionListener
// set up menu item for deleting a record
deleteItem = new JMenuItem( "Delete Record" );
deleteItem.setEnabled( false );
// register delete item listener
deleteItem.addActionListener(
 2003 Prentice Hall, Inc.
All rights reserved.
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
new ActionListener() { // anonymous inner class
public void actionPerformed( ActionEvent event )
{
// set up the GUI fields for editing
fields[ BankUI.ACCOUNT ].setEnabled( true );
fields[ BankUI.FIRSTNAME ].setEnabled( false );
fields[ BankUI.LASTNAME ].setEnabled( false );
fields[ BankUI.BALANCE ].setEnabled( false );
fields[ BankUI.TRANSACTION ].setEnabled( false );
Outline
TransactionProc
essor.java
actionButton.setEnabled( true );
actionButton.setText( "Delete" );
cancelButton.setEnabled( true );
userInterface.clearFields(); // reset the textfields
} // end method actionPerformed
} // end anonymous inner class
); // end call to addActionListener
// set up menu item for opening file
openItem = new JMenuItem( "New/Open File" );
 2003 Prentice Hall, Inc.
All rights reserved.
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// register open item listener
openItem.addActionListener(
new ActionListener() { // anonymous inner class
public void actionPerformed( ActionEvent event )
{
// try to open the file
if ( !openFile() )
return;
Outline
TransactionProc
essor.java
// set up the menu items
newItem.setEnabled( true );
updateItem.setEnabled( true );
deleteItem.setEnabled( true );
openItem.setEnabled( false );
// set the interface
userInterface.setVisible( true );
fields[ BankUI.ACCOUNT ].setEnabled( false );
fields[ BankUI.FIRSTNAME ].setEnabled( false );
fields[ BankUI.LASTNAME ].setEnabled( false );
fields[ BankUI.BALANCE ].setEnabled( false );
fields[ BankUI.TRANSACTION ].setEnabled( false );
} // end method actionPerformed
 2003 Prentice Hall, Inc.
All rights reserved.
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
} // end anonymous inner class
Outline
); // end call to addActionListener
// set up menu item for exiting program
exitItem = new JMenuItem( "Exit" );
TransactionProc
essor.java
// register exit item listener
exitItem.addActionListener(
new ActionListener() { // anonyomus inner class
public void actionPerformed( ActionEvent event )
{
try {
dataFile.closeFile(); // close the file
}
catch ( IOException ioException ) {
JOptionPane.showMessageDialog(
TransactionProcessor.this, "Error closing file",
"IO Error", JOptionPane.ERROR_MESSAGE );
}
finally {
System.exit( 0 ); // exit the program
}
 2003 Prentice Hall, Inc.
All rights reserved.
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
} // end method actionPerformed
} // end anonymous inner class
); // end call to addActionListener
Outline
TransactionProc
essor.java
// attach menu items to File menu
fileMenu.add( openItem );
fileMenu.add( newItem );
fileMenu.add( updateItem );
fileMenu.add( deleteItem );
fileMenu.addSeparator();
fileMenu.add( exitItem );
setSize( 400, 250 );
setVisible( true );
} // end constructor
public static void main( String args[] )
{
new TransactionProcessor();
}
 2003 Prentice Hall, Inc.
All rights reserved.
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
// get the file name and open the file
private boolean openFile()
{
// display dialog so user can select file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
int result = fileChooser.showOpenDialog( this );
Outline
TransactionProc
essor.java
Line 309
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return false;
// obtain selected file
File fileName = fileChooser.getSelectedFile();
// display error if file name invalid
if ( fileName == null || fileName.getName().equals( "" ) ) {
JOptionPane.showMessageDialog( this, "Invalid File Name",
"Bad File Name", JOptionPane.ERROR_MESSAGE );
return false;
}
try {
// call the helper method to open the file
dataFile = new FileEditor( fileName );
}
Create a FileEditor
object from the file name
 2003 Prentice Hall, Inc.
All rights reserved.
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
catch( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error Opening File",
"IO Error", JOptionPane.ERROR_MESSAGE );
return false;
}
return true;
} // end method openFile
// create, update or delete the record
private void performAction( String action )
{
try {
Outline
TransactionProc
essor.java
Line 323
Called when the first
Lines
action336-337
button is
pressed
// get the textfield values
String[] values = userInterface.getFieldValues();
int accountNumber = Integer.parseInt( values[ BankUI.ACCOUNT ] );
String firstName = values[ BankUI.FIRSTNAME ];
String lastName = values[ BankUI.LASTNAME ];
double balance = Double.parseDouble( values[ BankUI.BALANCE ] );
Create a new record
if ( action.equals( "Create" ) )
dataFile.newRecord( accountNumber, // create a new record
firstName, lastName, balance );
 2003 Prentice Hall, Inc.
All rights reserved.
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
else if ( action.equals( "Update" ) )
dataFile.updateRecord( accountNumber, // update record
firstName, lastName, balance );
else if ( action.equals( "Delete" ) )
dataFile.deleteRecord( accountNumber ); // delete record
else
JOptionPane.showMessageDialog( this, "Invalid Action",
"Error executing action", JOptionPane.ERROR_MESSAGE );
Outline
Update a record
TransactionProc
essor.java
Delete a record
Lines 340-341
Line 344
} // end try
catch( NumberFormatException format ) {
JOptionPane.showMessageDialog( this, "Bad Input",
"Number Format Error", JOptionPane.ERROR_MESSAGE );
}
catch( IllegalArgumentException badAccount ) {
JOptionPane.showMessageDialog( this, badAccount.getMessage(),
"Bad Account Number", JOptionPane.ERROR_MESSAGE );
}
catch( IOException ioException ) {
JOptionPane.showMessageDialog( this, "Error writing to the file",
"IO Error", JOptionPane.ERROR_MESSAGE );
}
 2003 Prentice Hall, Inc.
All rights reserved.
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
} // end method performAction
// input a record in the textfields and update the balance
private void displayRecord( String transaction )
{
try {
// get the account number
int accountNumber = Integer.parseInt(
userInterface.getFieldValues()[ BankUI.ACCOUNT ] );
// get the associated record
RandomAccessAccountRecord record =
dataFile.getRecord( accountNumber );
Outline
TransactionProc
essor.java
Line 369
Display a record in
the textfields
if ( record.getAccount() == 0 )
JOptionPane.showMessageDialog( this, "Record does not exist",
"Bad Account Number", JOptionPane.ERROR_MESSAGE );
// get the transaction
double change = Double.parseDouble( transaction );
// create a string array to send to the textfields
String[] values = { String.valueOf( record.getAccount() ),
record.getFirstName(), record.getLastName(),
String.valueOf( record.getBalance() + change ),
"Charge(+) or payment (-)" };
 2003 Prentice Hall, Inc.
All rights reserved.
392
393
userInterface.setFieldValues( values );
394
395
} // end try
396
397
catch( NumberFormatException format ) {
398
JOptionPane.showMessageDialog( this, "Bad Input",
399
"Number Format Error", JOptionPane.ERROR_MESSAGE );
400
}
401
402
catch ( IllegalArgumentException badAccount ) {
403
JOptionPane.showMessageDialog( this, badAccount.getMessage(),
404
"Bad Account Number", JOptionPane.ERROR_MESSAGE );
405
}
406
407
catch( IOException ioException ) {
408
JOptionPane.showMessageDialog( this, "Error reading the file",
409
"IO Error", JOptionPane.ERROR_MESSAGE );
410
}
411
412
} // end method displayRecord
413
414 } // end class TransactionProcessor
Outline
TransactionProc
essor.java
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 17.22: FileEditor.java
// This class declares methods that manipulate bank account
// records in a random access file.
import java.io.*;
import com.deitel.jhtp5.ch17.RandomAccessAccountRecord;
Outline
FileEditor.java
Line 15
public class FileEditor {
Line 22
RandomAccessFile file; // reference to the file
// open the file
public FileEditor( File fileName ) throws IOException
{
file = new RandomAccessFile( fileName, "rw" );
}
// close the file
public void closeFile() throws IOException
{
if ( file != null )
file.close();
}
Create a RandomAccessFile
from the file name provided
Close the object’s file
 2003 Prentice Hall, Inc.
All rights reserved.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// get a record from the file
public RandomAccessAccountRecord getRecord( int accountNumber )
throws IllegalArgumentException, NumberFormatException, IOException
{
RandomAccessAccountRecord record = new RandomAccessAccountRecord();
if ( accountNumber < 1 || accountNumber > 100 )
throw new IllegalArgumentException( "Out of range" );
// seek appropriate record in file
file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE );
Outline
FileEditor.java
Get a record
Line 26
from the file
Line 35
Position the file
Line 37 pointer
record.read( file );
Lines 44-45
return record;
Read a record
} // end method getRecord
// update record in file
public void updateRecord( int accountNumber, String firstName,
String lastName, double balance )
throws IllegalArgumentException, IOException
{
RandomAccessAccountRecord record = getRecord( accountNumber );
if ( accountNumber == 0 )
throw new IllegalArgumentException( "Account does not exist" );
Update a record
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// seek appropriate record in file
file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE );
record = new RandomAccessAccountRecord( accountNumber,
firstName, lastName, balance );
FileEditor.java
Line
Position
the53
file
pointer
Line 58
record.write( file ); // write updated record to file
} // end method updateRecord
// add record to file
public void newRecord( int accountNumber, String firstName,
String lastName, double balance )
throws IllegalArgumentException, IOException
{
RandomAccessAccountRecord record = getRecord( accountNumber );
Outline
Overwrite the
record
Lines
63-64
Line 73
Create a new record
if ( record.getAccount() != 0 )
throw new IllegalArgumentException( "Account already exists" );
// seek appropriate record in file
file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE );
Position the file
pointer
record = new RandomAccessAccountRecord( accountNumber,
firstName, lastName, balance );
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
77
78
record.write( file ); // write record to file
79
80
} // end method newRecord
FileEditor.java
81
82
// delete record from file
Write the
new
Line
78record
83
public void deleteRecord( int accountNumber )
84
throws IllegalArgumentException, IOException
85
{
Linea 83
Delete
record
86
RandomAccessAccountRecord record = getRecord( accountNumber );
87
Line 92
88
if ( record.getAccount() == 0 )
89
throw new IllegalArgumentException( "Account does not exist" );
90
Line 96
91
// seek appropriate record in file
Position the file
92
file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE );
pointer
93
94
// create a blank record to write to the file
95
record = new RandomAccessAccountRecord();
96
record.write( file );
Delete a record by
97
98
} // end method deleteRecord
overwriting the old record
99
with a blank record
100 } // end class EditFile
 2003 Prentice Hall, Inc.
All rights reserved.
17.13 New I/O APIs for the Java Platform
• Buffers
– Consolidate I/O operations
– Four properties
•
•
•
•
Capacity
Limit
Position
Mark
– Put and get operations
• Relative or absolute
– Clear, flip, rewind, reset
 2003 Prentice Hall, Inc. All rights reserved.
17.13 New I/O APIs for the Java Platform
• Channels
– Connection to an I/O device
• Interacts efficiently with buffers
– ReadableByteChannel interface
• Method read
– WriteableByteChannel interface
• Method write
– Scattering reads and gather writes
– Class FileChannel
 2003 Prentice Hall, Inc. All rights reserved.
17.13 New I/O APIs for the Java Platform
• File Locks
– Restricts access to a portion of a file
– FileChannel, position, size
– Exclusive or shared
• Charsets
– Package java.nio.charset
• Class Charset
– Methods decode, encode
• Class CharsetDecoder, CharsetEncoder
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Fig. 17.23: FileChannelTest.java
// Demonstrates FileChannel and ByteBuffer.
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class FileChannelTest {
private FileChannel fileChannel;
// no-arg constructor
public FileChannelTest()
{
// create random access file and get file channel
try {
RandomAccessFile file = new RandomAccessFile( "Test", "rw" );
fileChannel = file.getChannel();
}
catch ( IOException ioException ) {
ioException.printStackTrace();
}
Outline
FileChannelTest
Import the
java.nio and
.java
java.nio.channels
packages
Lines
4-5
Line 16
Get a channel by calling
method getChannel
} // end constructor FileChannelTest
 2003 Prentice Hall, Inc.
All rights reserved.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// write to writeChannel
public void writeToFile() throws IOException
{
// create buffer for writing
ByteBuffer buffer = ByteBuffer.allocate( 14 );
// write an int, a char and a double to buffer
buffer.putInt( 100 );
buffer.putChar( 'A' );
buffer.putDouble( 12.34 );
// flip buffer and write buffer to fileChannel
buffer.flip();
fileChannel.write( buffer );
}
// read from readChannel
public void readFromFile() throws IOException
{
String content = "";
// create buffer for read
ByteBuffer buffer = ByteBuffer.allocate( 14 );
Outline
FileChannelTest
Allocate
a buffer
.java
of 14
bytes
Fill the buffer with an
Line 28
integer, a character and
a double
Lines 31-33
Flip the buffer to
Line 36
prepare it for writing
Line 37
Write the buffer
to the
Line 46
FileChannel
Allocate a buffer
of 14 bytes
 2003 Prentice Hall, Inc.
All rights reserved.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// read buffer from fileChannel
fileChannel.position( 0 );
fileChannel.read( buffer );
// flip buffer for reading
buffer.flip();
// obtain content
content += buffer.getInt() + ", " + buffer.getChar() + ", " +
buffer.getDouble();
System.out.println( "File contains: " + content );
// close fileChannel
fileChannel.close();
} // end method readFromFile
Outline
Position the
FileChannel
FileChannelTest
at the beginning
.java and fill the
buffer with bytes
Flip the buffer to
49-50
prepare itLines
for reading
Line 53
Fill the buffer with an
integer,Lines
a character
56-57 and
a double
Line 62
Close the FileChannel
public static void main( String[] args )
{
FileChannelTest application = new FileChannelTest();
 2003 Prentice Hall, Inc.
All rights reserved.
70
71
72
73
74
75
76
77
78
79
80
// write to file and then read from file
try {
application.writeToFile();
application.readFromFile();
}
catch ( IOException ioException ) {
ioException.printStackTrace();
}
Outline
FileChannelTest
.java
}
} // end class FileChannelTest
File contains: 100, A, 12.34
 2003 Prentice Hall, Inc.
All rights reserved.