Download Files and Streams

Document related concepts
no text concepts found
Transcript
14
Files and
Streams
I can only assume that a “Do
Not File” document is filed
in a “Do Not File” file.
—Senator Frank Church
Senate Intelligence
Subcommittee Hearing, 1975
Consciousness … does not
appear to itself chopped up
in bits. … A “river” or a
“stream” are the metaphors
by which it is most naturally
described.
—William James
OBJECTIVES
In this chapter you will learn:
■
■
To create, read, write and update files.
To use class File to retrieve information about files and
directories.
■
The Java input/output stream class hierarchy.
I read part of it all the way
through.
■
The differences between text files and binary files.
■
Sequential-access file processing.
—Samuel Goldwyn
■
A great memory does not
make a philosopher, any
more than a dictionary can
be called grammar.
—John Henry, Cardinal
Newman
■
■
■
To use classes Scanner and Formatter to process
text files.
To use the FileInputStream and
FileOutputStream classes.
To use a JFileChooser dialog.
To use the ObjectInputStream and
ObjectOutputStream classes.
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
2
Chapter 14 Files and Streams
Self-Review Exercises
14.1
Fill in the blanks in each of the following statements:
a) Ultimately, all data items processed by a computer are reduced to combinations of
and
.
ANS: ones, zeros.
b) The smallest data item a computer can process is called a(n)
.
ANS: bit.
can sometimes be viewed as a group of related records.
c) A(n)
ANS: file.
d) Digits, letters and special symbols are referred to as
.
ANS: characters.
e) A database is a group of related
.
ANS: files.
f) Object
normally enables a program to output error messages to the screen.
ANS: System.err.
14.2
why.
Determine which of the following statements are true and which are false. If false, explain
14.3
a) The programmer must explicitly create the stream objects System.in, System.out and
System.err.
ANS: False. These three streams are created for the programmer when a Java application
begins executing.
b) When reading data from a file using class Scanner, if the programmer wishes to read
data in the file multiple times, the file must be closed and reopened to read from the
beginning of the file. This moves the file-position pointer back to the beginning of the
file.
ANS: True.
c) Method exists of class File returns true if the name specified as the argument to the
File constructor is a file or directory in the specified path.
ANS: True.
d) Binary files are human readable.
ANS: False. Text files are human readable.
e) An absolute path contains all the directories, starting with the root directory, that lead
to a specific file or directory.
ANS: True.
f) Class Formatter contains method printf, which enables formatted data to be output to
the screen or to a file.
ANS: False. Class Formatter contains method format, which enables formatted data to be
output to the screen or to a file.
Complete the following tasks, assuming that each applies to the same program:
a) Write a statement that opens file "oldmast.txt" for input—use Scanner variable inOldMaster.
ANS: Scanner inOldMaster = new Scanner( new File ( "oldmast.txt" ) );
b) Write a statement that opens file "trans.txt" for input—use Scanner variable inTransaction.
ANS: Scanner inTransaction = new Scanner( new File( "trans.txt" ) );
c) Write a statement that opens file "newmast.txt" for output (and creation)—use formatter variable outNewMaster.
ANS: Formatter outNewMaster = new Formatter( "newmast.txt" );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Self-Review Exercises
3
d) Write the statements needed to read a record from the file "oldmast.txt". The data
read should be used to create an object of class AccountRecord—use Scanner variable
inOldMaster. Assume that class AccountRecord is the same as the AccountRecord class
in Fig. 14.6
ANS: AccountRecord account = new AccountRecord();
account.setAccount( inOldMaster.nextInt() );
account.setFirstName( inOldMaster.next() );
account.setLastName( inOldMaster.next() );
account.setBalance( inOldMaster.nextDouble() );
e) Write the statements needed to read a record from the file "trans.txt". The record is
an object of class TransactionRecord—use Scanner variable inTransaction. Assume
that class TransactionRecord contains method setAccount (which takes an int) to set
the account number and method setAmount (which takes a double) to set the amount
of the transaction.
ANS: TransactionRecord transaction = new Transaction();
transaction.setAccount( inTransaction.nextInt() );
transaction.setAmount( inTransaction.nextDouble() );
f) Write a statement that outputs a record to the file "newmast.txt". The record is an object of type AccountRecord—use Formatter variable outNewMaster.
ANS: outNewMaster.format( "%d %s %s %.2f\n",
account.getAccount(), account.getFirstName(),
account.getLastName(), account.getBalance() );
14.4
Complete the following tasks, assuming that each applies to the same program:
a) Write a statement that opens file "oldmast.ser" for input—use ObjectInputStream
variable inOldMaster to wrap a FileInputStream object.
ANS: ObjectInputStream inOldMaster = new ObjectInputStream(
new FileInputStream( "oldmast.ser" ) );
b) Write a statement that opens file "trans.ser" for input—use ObjectInputStream variable inTransaction to wrap a FileInputStream object.
ANS: ObjectInputStream inTransaction = new ObjectInputStream(
new FileInputStream( "trans.ser" ) );
c) Write a statement that opens file "newmast.ser" for output (and creation)—use
jectOutputStream variable outNewMaster to wrap a FileOutputStream.
Ob-
ANS: ObjectOutputStream outNewMaster = new ObjectOutputStream(
new FileOutputStream( "newmast.ser" ) );
d) Write a statement that reads a record from the file "oldmast.ser". The record is an object of class AccountRecordSerializable—use ObjectInputStream variable inOldMaster.
Assume class AccountRecordSerializable is the same as the
AccountRecordSerializable class in Fig. 14.17.
ANS: accountRecord = ( AccountRecordSerializable ) inOldMaster.readObject();
e) Write a statement that reads a record from the file "trans.ser". The record is an object
of class TransactionRecord—use ObjectInputStream variable inTransaction.
ANS: transactionRecord = ( TransactionRecord ) inTransaction.readObject();
f) Write a statement that outputs a record to the file "newmast.ser". The record is an object of type AccountRecordSerializable—use ObjectOutputStream variable outNewMaster.
ANS: outNewMaster.writeObject( newAccountRecord );
14.5
Find the error in each block of code and show how to correct it.
a) Assume that account, company and amount are declared.
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
4
Chapter 14 Files and Streams
ObjectOutputStream outputStream;
outputStream.writeInt( account );
outputStream.writeChars( company );
outputStream.writeDouble( amount );
ANS: Error: The file has not been opened before the attempt is made to output data to the
stream.
Correction: Open a file for output by creating a new ObjectOutputStream object that
wraps a FileOutputStream object.
b) The following statements should read a record from the file "payables.txt". The Scanner variable inPayable should be used to refer to this file.
Scanner inPayable = new Scanner( new File( "payables.txt" ) );
PayablesRecord record = ( PayablesRecord ) inPayable.readObject();
ANS: Error: This example uses text files with a Scanner, there is no object serialization. As
a result, method readObject cannot be used to read that data from the file. Each piece
of data must be read separately, then used to create a PayablesRecord object.
Correction: Use methods of inPayable to read each piece of the PayablesRecord object.
Exercises
14.6
Fill in the blanks in each of the following statements:
a) Computers store large amounts of data on secondary storage devices as
.
ANS: files
b) A(n)
is composed of several fields.
ANS: record
c) To facilitate the retrieval of specific records from a file, one field in each record is chosen
as a(n)
.
ANS: record key
d) Files that are created using byte-based streams are referred to as
files, while
files created using character-based streams are referred to as
files.
ANS: binary, text
e) The standard stream objects are
,
and
.
ANS: System.in, System.out, System.err
14.7 (File Matching) Self-Review Exercise 14.3 asks the reader to write a series of single statements. Actually, these statements form the core of an important type of file-processing program,
namely, a file-matching program. In commercial data processing, it is common to have several files
in each application system. In an accounts receivable system, for example, there is generally a master
file containing detailed information about each customer, such as the customer’s name, address,
telephone number, outstanding balance, credit limit, discount terms, contract arrangements and
possibly a condensed history of recent purchases and cash payments.
As transactions occur (i.e., sales are made and payments arrive in the mail), information about
them is entered into a file. At the end of each business period (a month for some companies, a
week for others, and a day in some cases), the file of transactions (called "trans.txt") is applied to
the master file (called "oldmast.txt") to update each account’s purchase and payment record.
During an update, the master file is rewritten as the file "newmast.txt", which is then used at the
end of the next business period to begin the updating process again.
File-matching programs must deal with certain problems that do not arise in single-file programs. For example, a match does not always occur. If a customer on the master file has not made
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
5
any purchases or cash payments in the current business period, no record for this customer will
appear on the transaction file. Similarly, a customer who did make some purchases or cash payments could have just moved to this community, and if so, the company may not have had a
chance to create a master record for this customer.
Write a complete file-matching accounts receivable program. Use the account number on
each file as the record key for matching purposes. Assume that each file is a sequential text file with
records stored in increasing account-number order.
a) Define class TransactionRecord. Objects of this class contain an account number and
amount for the transaction. Provide methods to modify and retrieve these values.
b) Modify class AccountRecord in Fig. 14.6 to include method combine, which takes a
TransactionRecord object and combines the balance of the AccountRecord object and
amount value of the TransactionRecord object.
c) Write a program to create data for testing the program. Use the sample account data in
Figs. 14.24 and 14.25. Run the program to create the files trans.txt and oldmast.txt,
to be used by your file-matching program.
Master file
Account number
Name
Balance
100
Alan Jones
348.17
300
Mary Smith
27.19
500
Sam Sharp
0.00
700
Suzy Green
–14.22
Fig. 14.1 | Sample data for master file.
Transaction file
Account number
Transaction amount
100
27.14
300
62.11
400
100.56
900
82.17
Fig. 14.2 | Sample data for transaction file.
d) Create class FileMatch to perform the file-matching functionality. The class should
contain methods that read oldmast.txt and trans.txt. When a match occurs (i.e.,
records with the same account number appear in both the master file and the transaction file), add the dollar amount in the transaction record to the current balance in the
master record, and write the "newmast.txt" record. (Assume that purchases are indicated by positive amounts in the transaction file and payments by negative amounts.)
When there is a master record for a particular account, but no corresponding transaction record, merely write the master record to "newmast.txt". When there is a transac-
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
6
Chapter 14 Files and Streams
tion record, but no corresponding master record, print to a log file the message
"Unmatched transaction record for account number…" (fill in the account number
from the transaction record). The log file should be a text file named "log.txt".
ANS:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Exercise 14.7 Solution: AccountRecord.java
// A class that represents one record of information.
public class AccountRecord
{
private int account;
private String firstName;
private String lastName;
private double balance;
// no-argument constructor calls other constructor with default values
public AccountRecord()
{
this( 0, "", "", 0.0 ); // call four-argument constructor
} // end no-argument AccountRecord constructor
// initialize a record
public AccountRecord( int acct, String first, String last, double bal )
{
setAccount( acct );
setFirstName( first );
setLastName( last );
setBalance( bal );
} // end four-argument AccountRecord constructor
// add a transaction to an account record
public void combine( TransactionRecord transaction )
{
balance = balance + transaction.getAmount();
} // end method combine
// set account number
public void setAccount( int acct )
{
account = acct;
} // end method setAccount
// get account number
public int getAccount()
{
return account;
} // end method getAccount
// set first name
public void setFirstName( String first )
{
firstName = first;
} // end method setFirstName
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
50
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
76
77
78
79
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
7
// get first name
public String getFirstName()
{
return firstName;
} // end method getFirstName
// set last name
public void setLastName( String last )
{
lastName = last;
} // end method setLastName
// get last name
public String getLastName()
{
return lastName;
} // end method getLastName
// set balance
public void setBalance( double bal )
{
balance = bal;
} // end method setBalance
// get balance
public double getBalance()
{
return balance;
} // end method getBalance
} // end class AccountRecord
// Exercise 14.7 Solution: TransactionRecord.java
// A class that represents one transaction record.
public class TransactionRecord
{
private int account;
private double amount;
// no-argument constructor calls other constructor with default values
public TransactionRecord()
{
this( 0, 0.0 );
} // end no-argument TransactionRecord
// initialize a record
public TransactionRecord( int acct, double amt )
{
setAccount( acct );
setAmount( amt );
} // end two-argument TransactionRecord
// set account number
public void setAccount( int acct )
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
8
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
28
29
Chapter 14 Files and Streams
{
account = acct;
} // end method setAccount
// get account number
public int getAccount()
{
return account;
} // end method getAccount
// set amount
public void setAmount( double amt )
{
amount = amt;
} // end method setAmount
// get amount
public double getAmount()
{
return amount;
} // end method getAmount
} // end class TransactionRecord
// Exercise 14.7 Solution: CreateData.java
// Create data to put into an account file and a transactions file.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.IllegalFormatException;
public class CreateData
{
public static void main( String args[] )
{
Formatter outOldMaster = null;
Formatter outTransaction = null;
AccountRecord accounts[] = new AccountRecord[ 4 ];
TransactionRecord transactions[] = new TransactionRecord[ 4 ];
// create
accounts[
accounts[
accounts[
accounts[
account records
0 ] = new AccountRecord(
1 ] = new AccountRecord(
2 ] = new AccountRecord(
3 ] = new AccountRecord(
// create transactions
transactions[ 0 ] = new
transactions[ 1 ] = new
transactions[ 2 ] = new
transactions[ 3 ] = new
100,
300,
500,
700,
"Alan", "Jones", 348.17 );
"Mary", "Smith", 27.19 );
"Sam", "Sharp", 0.00 );
"Suzy", "Green", -14.22 );
TransactionRecord(
TransactionRecord(
TransactionRecord(
TransactionRecord(
100,
300,
400,
900,
27.14 );
62.11 );
100.56 );
82.17 );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
71
72
73
74
75
76
77
78
79
80
81
82
83
try
{
9
// file stream for output file
outOldMaster = new Formatter( "oldmast.txt" );
for ( int i = 0; i < accounts.length; i++ )
{
outOldMaster.format( "%d %s %s %.2f\n",
accounts[ i ].getAccount(), accounts[ i ].getFirstName(),
accounts[ i ].getLastName(), accounts[ i ].getBalance() );
} // end for
// file stream for output file
outTransaction = new Formatter( "trans.txt" );
for ( int i = 0; i < transactions.length; i++ )
{
outTransaction.format( "%d %.2f\n",
transactions[ i ].getAccount(),
transactions[ i ].getAmount() );
} // end for
} // end try
catch ( SecurityException securityException )
{
System.err.println(
"You do not have write access to this file." );
System.exit( 1 );
} // end catch
catch ( FileNotFoundException fileNotFoundException )
{
System.err.println( "Error creating file." );
System.exit( 1 );
} // end catch
catch ( IllegalFormatException formatException )
{
System.err.println( "Error with output." );
System.exit( 1 );
} // end catch
catch ( FormatterClosedException closedException )
{
System.err.println(
"Error writing to file - file has been closed." );
System.exit( 1 );
} // end catch
finally
{
if ( outOldMaster != null )
outOldMaster.close();
if ( outTransaction != null )
outTransaction.close();
} // end finally
} // end main
} // end class CreateData
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
10
Chapter 14 Files and Streams
ANS: Contents of oldmast.txt after CreateData.java is executed:
100
300
500
700
Alan Jones 348.17
Mary Smith 27.19
Sam Sharp 0.00
Suzy Green -14.22
ANS: Contents of trans.txt after CreateData.java is executed:
100
300
400
900
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
28
29
30
31
32
33
27.14
62.11
100.56
82.17
// Exercise 14.7 Solution: FileMatch.java
// Combine an account file with a transactions file into a
// new account file.
import java.io.File;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.IllegalFormatException;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class FileMatch
{
private static Scanner inOldMaster;
private static Scanner inTransaction;
private static Formatter outNewMaster;
private static Formatter logFile;
private static TransactionRecord transaction;
private static AccountRecord account;
public FileMatch()
{
transaction = new TransactionRecord();
account = new AccountRecord();
} // end FileMatch constructor
public void openFiles()
{
try
{
// file streams for input and output files
inOldMaster = new Scanner( new File( "oldmast.txt" ) );
inTransaction = new Scanner( new File( "trans.txt" ) );
outNewMaster = new Formatter( "newmast.txt" );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
34
35
36
37
38
39
40
41
42
43
44
45
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
logFile = new Formatter( "log.txt" );
} // end try
catch ( Exception exception )
{
System.err.println( "Error opening the files." );
} // end catch
} // end method openFiles
public void processFiles()
{
int transactionAccountNumber;
int accountNumber;
try // block for reading/writing all records
{
// get a transaction record and its account number
transaction = getTransactionRecord();
// if the transaction is null, we are done
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
// get an account record and its account number
account = getAccountRecord();
// if the account is null, we are done
if ( account == null )
return;
accountNumber = account.getAccount();
while ( accountNumber != 0 )
{
while ( accountNumber < transactionAccountNumber )
{
// there is no transaction for this account
outNewMaster.format( "%d %s %s %.2f\n",
account.getAccount(), account.getFirstName(),
account.getLastName(), account.getBalance() );
account = getAccountRecord(); // get a new account
if ( account == null )
return;
accountNumber = account.getAccount();
} // end while
// if there is a transaction for this account
if ( accountNumber == transactionAccountNumber )
{
// combine the records
account.combine( transaction );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
11
12
90
91
92
93
94
95
96
97
98
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
Chapter 14 Files and Streams
// write to the master file
outNewMaster.format( "%d %s %s %.2f\n",
account.getAccount(), account.getFirstName(),
account.getLastName(), account.getBalance() );
// get a new transaction
transaction = getTransactionRecord();
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
// get a new account
account = getAccountRecord();
if ( account == null )
return;
accountNumber = account.getAccount();
} // end if
while ( transactionAccountNumber < accountNumber )
{
// there is no account for this transaction
logFile.format( "%s %d\n",
"Unmatched transaction record for account number",
transactionAccountNumber );
// get a new transaction
transaction = getTransactionRecord();
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
} // end while
} // end outer while
} // end try
catch ( FormatterClosedException closedException )
{
System.err.println(
"Error writing to file - file has been closed." );
System.exit( 1 );
} // end catch
catch ( IllegalFormatException formatException )
{
System.err.println( "Error with output." );
System.exit( 1 );
} // end catch
} // end method processFiles
public void closeFiles()
{
try // close the files
{
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
146
147
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
if ( inTransaction != null )
inTransaction.close();
if ( outNewMaster != null )
outNewMaster.close();
if ( inOldMaster != null )
inOldMaster.close();
if ( logFile != null )
logFile.close();
} // end try
catch ( Exception exception )
{
System.err.println( "Error closing the files." );
System.exit( 1 );
} // end catch
} // end method closeFiles
// get a transaction record
private TransactionRecord getTransactionRecord()
{
// try to read the record
try
{
if ( inTransaction.hasNext() )
{
transaction.setAccount( inTransaction.nextInt() );
transaction.setAmount( inTransaction.nextDouble() );
return transaction;
} // end if
else // we have hit end of transaction file
{
// these remaining accounts have
while ( inOldMaster.hasNext() )
{
account.setAccount( inOldMaster.nextInt() );
account.setFirstName( inOldMaster.next() );
account.setLastName( inOldMaster.next() );
account.setBalance( inOldMaster.nextDouble() );
// store in new master
outNewMaster.format( "%d %s %s %.2f\n",
account.getAccount(), account.getFirstName(),
account.getLastName(), account.getBalance() );
} // end while
} // end else
} // end try
catch ( FormatterClosedException closedException )
{
System.err.println(
"Error writing to file - file has been closed." );
System.exit( 1 );
} // end catch
catch ( IllegalFormatException formatException )
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
13
14
202
203
204
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
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
Chapter 14 Files and Streams
{
System.err.println( "Error with output." );
System.exit( 1 );
} // end catch
catch ( NoSuchElementException elementException )
{
System.err.println( "Invalid input from file." );
} // end catch
// return null - no more records
return null;
} // end method getTransactionRecord
// get an account record
private AccountRecord getAccountRecord()
{
try // try to read an account record
{
if ( inOldMaster.hasNext() )
{
account.setAccount( inOldMaster.nextInt() );
account.setFirstName( inOldMaster.next() );
account.setLastName( inOldMaster.next() );
account.setBalance( inOldMaster.nextDouble() );
return account;
} // end if
else // we have hit end of old master file
{
logFile.format( "%s %d\n",
"Unmatched transaction record for account number",
transaction.getAccount() );
// these records are transactions without accounts
while ( inTransaction.hasNext() )
{
transaction.setAccount( inTransaction.nextInt() );
transaction.setAmount( inTransaction.nextDouble() );
} // end while
} // end else
} // end try
catch ( FormatterClosedException closedException )
{
System.err.println(
"Error writing to file - file has been closed." );
System.exit( 1 );
} // end catch
catch ( IllegalFormatException formatException )
{
System.err.println( "Error with output." );
System.exit( 1 );
} // end catch
catch ( NoSuchElementException elementException )
{
System.err.println( "Invalid input from file." );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
15
257
} // end catch
258
259
return null;
260
} // end method getAccountRecord
261 } // end class FileMatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Exercise 14.7 Solution: FileMatchTest.java
// Tests FileMatch program.
public class FileMatchTest
{
public static void main( String args[] )
{
FileMatch application = new FileMatch();
application.openFiles();
application.processFiles();
application.closeFiles();
} // end main
} // end class FileMatchTest
ANS: Contents of newmast.txt after FileMatchTest is executed.
100
300
500
700
Alan Jones 375.31
Mary Smith 89.30
Sam Sharp 0.00
Suzy Green -14.22
ANS: Contents of log.txt after FileMatchTest is executed.
Unmatched transaction record for account number 400
Unmatched transaction record for account number 900
14.8 (File Matching with Multiple Transactions) It is possible (and actually common) to have several transaction records with the same record key. This situation occurs, for example, when a customer makes several purchases and cash payments during a business period. Rewrite your accounts
receivable file-matching program from Exercise 14.8 to provide for the possibility of handling several transaction records with the same record key. Modify the test data of CreateData.java to include the additional transaction records in Fig. 14.26.
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
16
Chapter 14 Files and Streams
Account number
Dollar amount
300
83.89
700
80.78
700
1.53
Fig. 14.3 | Additional transaction records.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Exercise 14.8 Solution: AccountRecord.java
// A class that represents one record of information.
public class AccountRecord
{
private int account;
private String firstName;
private String lastName;
private double balance;
// no-argument constructor calls other constructor with default values
public AccountRecord()
{
this( 0, "", "", 0.0 ); // call four-argument constructor
} // end no-argument AccountRecord constructor
// initialize a record
public AccountRecord( int acct, String first, String last, double bal )
{
setAccount( acct );
setFirstName( first );
setLastName( last );
setBalance( bal );
} // end four-argument AccountRecord constructor
// add a transaction to an account record
public void combine( TransactionRecord transaction )
{
balance = balance + transaction.getAmount();
} // end method combine
// set account number
public void setAccount( int acct )
{
account = acct;
} // end method setAccount
// get account number
public int getAccount()
{
return account;
} // end method getAccount
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
44
45
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
71
72
73
74
75
76
77
78
79
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
17
// set first name
public void setFirstName( String first )
{
firstName = first;
} // end method setFirstName
// get first name
public String getFirstName()
{
return firstName;
} // end method getFirstName
// set last name
public void setLastName( String last )
{
lastName = last;
} // end method setLastName
// get last name
public String getLastName()
{
return lastName;
} // end method getLastName
// set balance
public void setBalance( double bal )
{
balance = bal;
} // end method setBalance
// get balance
public double getBalance()
{
return balance;
} // end method getBalance
} // end class AccountRecord
// Exercise 14.8 Solution: TransactionRecord.java
// A class that represents one transaction record.
public class TransactionRecord
{
private int account;
private double amount;
// no-argument constructor calls other constructor with default values
public TransactionRecord()
{
this( 0, 0.0 );
} // end no-argument TransactionRecord
// initialize a record
public TransactionRecord( int acct, double amt )
{
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
18
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Chapter 14 Files and Streams
setAccount( acct );
setAmount( amt );
} // end two-argument TransactionRecord
// set account number
public void setAccount( int acct )
{
account = acct;
} // end method setAccount
// get account number
public int getAccount()
{
return account;
} // end method getAccount
// set amount
public void setAmount( double amt )
{
amount = amt;
} // end method setAmount
// get amount
public double getAmount()
{
return amount;
} // end method getAmount
} // end class TransactionRecord
// Exercise 14.8 Solution: CreateData.java
// Create data to put into an account file and a transactions file.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.IllegalFormatException;
public class CreateData
{
public static void main( String args[] )
{
Formatter outOldMaster = null;
Formatter outTransaction = null;
AccountRecord accounts[] = new AccountRecord[ 4 ];
TransactionRecord transactions[] = new TransactionRecord[ 4 ];
// create
accounts[
accounts[
accounts[
accounts[
account records
0 ] = new AccountRecord(
1 ] = new AccountRecord(
2 ] = new AccountRecord(
3 ] = new AccountRecord(
100,
300,
500,
700,
"Alan", "Jones", 348.17 );
"Mary", "Smith", 27.19 );
"Sam", "Sharp", 0.00 );
"Suzy", "Green", -14.22 );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
24
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
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
// create transactions
transactions[ 0 ] = new
transactions[ 1 ] = new
transactions[ 2 ] = new
transactions[ 3 ] = new
try
{
TransactionRecord(
TransactionRecord(
TransactionRecord(
TransactionRecord(
100,
300,
300,
900,
19
27.14 );
62.11 );
-10.00 );
82.17 );
// file stream for output file
outOldMaster = new Formatter( "oldmast.txt" );
for ( int i = 0; i < accounts.length; i++ )
{
outOldMaster.format( "%d %s %s %.2f\n",
accounts[ i ].getAccount(), accounts[ i ].getFirstName(),
accounts[ i ].getLastName(), accounts[ i ].getBalance() );
} // end for
// file stream for output file
outTransaction = new Formatter( "trans.txt" );
for ( int i = 0; i < transactions.length; i++ )
{
outTransaction.format( "%d %.2f\n",
transactions[ i ].getAccount(),
transactions[ i ].getAmount() );
} // end for
} // end try
catch ( SecurityException securityException )
{
System.err.println(
"You do not have write access to this file." );
System.exit( 1 );
} // end catch
catch ( FileNotFoundException fileNotFoundException )
{
System.err.println(
"Error creating file." );
System.exit( 1 );
} // end catch
catch ( FormatterClosedException closedException )
{
System.err.println(
"Error writing to file - file has been closed." );
System.exit( 1 );
} // end catch
catch ( IllegalFormatException formatException )
{
System.err.println( "Error with output." );
System.exit( 1 );
} // end catch
finally
{
if ( outOldMaster != null )
outOldMaster.close();
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
20
79
80
81
82
83
84
Chapter 14 Files and Streams
if ( outTransaction != null )
outTransaction.close();
} // end finally
} // end main
} // end class CreateData
ANS: Contents of oldmast.txt after CreateData.java is executed:
100
300
500
700
Alan Jones 348.17
Mary Smith 27.19
Sam Sharp 0.00
Suzy Green -14.22
ANS: Contents of trans.txt after CreateData.java is executed:
100
300
300
900
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
27.14
62.11
-10.00
82.17
// Exercise 14.8 Solution: FileMatch.java
// Combine an account file with a transactions file into a
// new account file.
import java.io.File;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.IllegalFormatException;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class FileMatch
{
private static Scanner inOldMaster;
private static Scanner inTransaction;
private static Formatter outNewMaster;
private static Formatter logFile;
private static TransactionRecord transaction;
private static AccountRecord account;
public FileMatch()
{
transaction = new TransactionRecord();
account = new AccountRecord();
} // end FileMatch constructor
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
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
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
public void openFiles()
{
try
{
// file streams for input and output files
inOldMaster = new Scanner( new File( "oldmast.txt" ) );
inTransaction = new Scanner( new File( "trans.txt" ) );
outNewMaster = new Formatter( "newmast.txt" );
logFile = new Formatter( "log.txt" );
} // end try
catch ( Exception exception )
{
System.err.println( "Error opening the files." );
} // end catch
} // end method openFiles
public void processFiles()
{
int transactionAccountNumber;
int accountNumber;
try // block for reading/writing all records
{
// get a transaction record and its account number
transaction = getTransactionRecord();
// if the transaction is null, we are done
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
// get an account record and its account number
account = getAccountRecord();
// if the account is null, we are done
if ( account == null )
return;
accountNumber = account.getAccount();
while ( accountNumber != 0 )
{
while ( accountNumber < transactionAccountNumber )
{
// there is no transaction for this account
outNewMaster.format( "%d %s %s %.2f\n",
account.getAccount(), account.getFirstName(),
account.getLastName(), account.getBalance() );
account = getAccountRecord(); // get a new account
if ( account == null )
return;
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
21
22
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
Chapter 14 Files and Streams
accountNumber = account.getAccount();
} // end while
// if there is a transaction for this account
if ( accountNumber == transactionAccountNumber )
{
while ( accountNumber == transactionAccountNumber )
{
// combine the records
account.combine( transaction );
// get a new transaction
transaction = getTransactionRecord();
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
} // end while
// write them to the master file
outNewMaster.format( "%d %s %s %.2f\n",
account.getAccount(), account.getFirstName(),
account.getLastName(), account.getBalance() );
// get a new account
account = getAccountRecord();
if ( account == null )
return;
accountNumber = account.getAccount();
} // end if
while ( transactionAccountNumber < accountNumber )
{
// there is no account for this transaction
logFile.format( "%s %d\n",
"Unmatched transaction record for account number",
transactionAccountNumber );
// get a new transaction
transaction = getTransactionRecord();
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
} // end while
} // end outer while
} // end try
catch ( FormatterClosedException closedException )
{
System.err.println(
"Error writing to file - file has been closed." );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
136
137
138
139
140
141
142
143
144
145
146
147
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
System.exit( 1 );
} // end catch
catch ( IllegalFormatException formatException )
{
System.err.println( "Error with output." );
System.exit( 1 );
} // end catch
} // end method processFiles
public void closeFiles()
{
try // close the files
{
if ( inTransaction != null )
inTransaction.close();
if ( outNewMaster != null )
outNewMaster.close();
if ( inOldMaster != null )
inOldMaster.close();
if ( logFile != null )
logFile.close();
} // end try
catch ( Exception exception )
{
System.err.println( "Error closing the files." );
System.exit( 1 );
} // end catch
} // end method closeFiles
// get a transaction record
private TransactionRecord getTransactionRecord()
{
// try to read the record
try
{
if ( inTransaction.hasNext() )
{
transaction.setAccount( inTransaction.nextInt() );
transaction.setAmount( inTransaction.nextDouble() );
return transaction;
} // end if
else // we have hit end of transaction file
{
// these remaining accounts have
while ( inOldMaster.hasNext() )
{
account.setAccount( inOldMaster.nextInt() );
account.setFirstName( inOldMaster.next() );
account.setLastName( inOldMaster.next() );
account.setBalance( inOldMaster.nextDouble() );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
23
24
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
Chapter 14 Files and Streams
// store in new master
outNewMaster.format( "%d %s %s %.2f\n",
account.getAccount(), account.getFirstName(),
account.getLastName(), account.getBalance() );
} // end while
} // end else
} // end try
catch ( FormatterClosedException closedException )
{
System.err.println(
"Error writing to file - file has been closed." );
System.exit( 1 );
} // end catch
catch ( IllegalFormatException formatException )
{
System.err.println( "Error with output." );
System.exit( 1 );
} // end catch
catch ( NoSuchElementException elementException )
{
System.err.println( "Invalid input from file." );
} // end catch
// return null - no more records
return null;
} // end method getTransactionRecord
// get an account record
private AccountRecord getAccountRecord()
{
try // try to read an account record
{
if ( inOldMaster.hasNext() )
{
account.setAccount( inOldMaster.nextInt() );
account.setFirstName( inOldMaster.next() );
account.setLastName( inOldMaster.next() );
account.setBalance( inOldMaster.nextDouble() );
return account;
} // end if
else // we have hit end of old master file
{
logFile.format( "%s %d\n",
"Unmatched transaction record for account number",
transaction.getAccount() );
// these records are transactions without accounts
while ( inTransaction.hasNext() )
{
transaction.setAccount( inTransaction.nextInt() );
transaction.setAmount( inTransaction.nextDouble() );
} // end while
} // end else
} // end try
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
246
catch ( FormatterClosedException closedException )
247
{
248
System.err.println(
249
"Error writing to file - file has been closed." );
250
System.exit( 1 );
251
} // end catch
252
catch ( IllegalFormatException formatException )
253
{
254
System.err.println( "Error with output." );
255
System.exit( 1 );
256
} // end catch
257
catch ( NoSuchElementException elementException )
258
{
259
System.err.println( "Invalid input from file." );
260
} // end catch
261
262
return null;
263
} // end method getAccountRecord
264 } // end class FileMatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Exercise 14.8 Solution: FileMatchTest.java
// Tests FileMatch program.
public class FileMatchTest
{
public static void main( String args[] )
{
FileMatch application = new FileMatch();
application.openFiles();
application.processFiles();
application.closeFiles();
} // end main
} // end class FileMatchTest
ANS: Contents of newmast.txt after FileMatchTest is executed.
100
300
500
700
Alan Jones 375.31
Mary Smith 79.30
Sam Sharp 0.00
Suzy Green -14.22
ANS: Contents of log.txt after FileMatchTest is executed.
Unmatched transaction record for account number 900
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
25
26
Chapter 14 Files and Streams
14.9 (File Matching with Object Serialization) Recreate your solution for Exercise 14.9 using object serialization. Use the statements from Exercise 14.4 as your basis for this program. You may
want to create applications to read the data stored in the .ser files—the code in Section 14.6.2 can
be modified for this purpose.
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Exercise 14.9 Solution: AccountRecordSerializable.java
// A class that represents one record of information.
import java.io.Serializable;
public class AccountRecordSerializable implements Serializable
{
private int account;
private String firstName;
private String lastName;
private double balance;
// no-argument constructor calls other constructor with default values
public AccountRecordSerializable()
{
this( 0, "", "", 0.0 ); // call four-argument constructor
} // end no-argument AccountRecordSerializable constructor
// initialize a record
public AccountRecordSerializable(
int acct, String first, String last, double bal )
{
setAccount( acct );
setFirstName( first );
setLastName( last );
setBalance( bal );
} // end four-argument AccountRecordSerializable constructor
// add a transaction record to an account record
public void combine( TransactionRecord transaction )
{
balance = balance + transaction.getAmount();
} // end method combine
// set account number
public void setAccount( int acct )
{
account = acct;
} // end method setAccount
// get account number
public int getAccount()
{
return account;
} // end method getAccount
// set first name
public void setFirstName( String first )
{
firstName = first;
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
50
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
76
77
78
79
80
81
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
27
} // end method setFirstName
// get first name
public String getFirstName()
{
return firstName;
} // end method getFirstName
// set last name
public void setLastName( String last )
{
lastName = last;
} // end method setLastName
// get last name
public String getLastName()
{
return lastName;
} // end method getLastName
// set balance
public void setBalance( double bal )
{
balance = bal;
} // end method setBalance
// get balance
public double getBalance()
{
return balance;
} // end method getBalance
} // end class AccountRecordSerializable
// Exercise 14.9 Solution: TransactionRecord.java
// A class that represents one transaction record.
import java.io.Serializable;
public class TransactionRecord implements Serializable
{
private int account;
private double amount;
// no-argument constructor calls other constructor with default values
public TransactionRecord()
{
this( 0, 0.0 );
} // end no-argument TransactionRecord
// initialize a record
public TransactionRecord( int acct, double amt )
{
setAccount( acct );
setAmount( amt );
} // end two-argument TransactionRecord
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
28
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
Chapter 14 Files and Streams
// set account number
public void setAccount( int acct )
{
account = acct;
} // end method setAccount
// get account number
public int getAccount()
{
return account;
} // end method getAccount
// set amount
public void setAmount( double amt )
{
amount = amt;
} // end method setAmount
// get amount
public double getAmount()
{
return amount;
} // end method getAmount
} // end class TransactionRecord
// Exercise 14.9 Solution: CreateData.java
// Create data to put into an account file and a transactions file.
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class CreateData
{
private static ObjectOutputStream outOldMaster, outTransaction;
public static void main( String args[] )
{
try
{
try
{
// file streams for output files
outOldMaster = new ObjectOutputStream(
new FileOutputStream( "oldmast.ser" ) );
outTransaction = new ObjectOutputStream(
new FileOutputStream( "trans.ser" ) );
} // end try
catch ( IOException io )
{
System.err.println( "Error opening the file." );
} // end catch
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
try
{
29
outOldMaster.writeObject( new AccountRecordSerializable(
100, "Alan", "Jones", 348.17 ) );
outOldMaster.writeObject( new AccountRecordSerializable(
300, "Mary", "Smith", 27.19 ) );
outOldMaster.writeObject( new AccountRecordSerializable(
500, "Sam", "Sharp", 0.00 ) );
outOldMaster.writeObject( new AccountRecordSerializable(
700, "Suzy", "Green", -14.22 ) );
outTransaction.writeObject(
new TransactionRecord( 100, 27.14 ) );
outTransaction.writeObject(
new TransactionRecord( 300, 62.11 ) );
outTransaction.writeObject(
new TransactionRecord( 300, -10.00 ) );
outTransaction.writeObject(
new TransactionRecord( 400, 100.56 ) );
outTransaction.writeObject(
new TransactionRecord( 900, 82.17 ) );
} // end try
catch ( IOException io )
{
System.out.println( "Error reading or writing to the file." );
System.exit( 1 );
} // end catch
}
finally // close the files
{
try
{
if ( outTransaction != null )
outTransaction.close();
if ( outOldMaster != null )
outOldMaster.close();
} // end try
catch ( IOException io )
{
System.err.println( "Error closing the file." );
System.exit( 1 );
} // end catch
} // end finally
} // end main
} // end class CreateData
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
30
Chapter 14 Files and Streams
ANS: Contents of oldmast.ser after CreateData.java is executed:
100
300
500
700
Alan Jones 348.17
Mary Smith 27.19
Sam Sharp 0.00
Suzy Green -14.22
ANS: Contents of trans.ser after CreateData.java is executed:
100
300
300
400
900
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
28
29
30
31
32
33
34
27.14
62.11
-10.00
100.56
82.17
// Exercise 14.9 Solution: FileMatch.java
// Combine account file and a transactions file into a new account file.
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ClassNotFoundException;
import java.util.Formatter;
public class FileMatch
{
private static ObjectInputStream inOldMaster;
private static ObjectInputStream inTransaction;
private static ObjectOutputStream outNewMaster;
private static Formatter logFile;
private static TransactionRecord transaction;
private static AccountRecordSerializable account;
public FileMatch()
{
transaction = new TransactionRecord();
account = new AccountRecordSerializable();
} // end FileMatch constructor
public void openFiles()
{
try
{
// file streams for input and output files
inOldMaster = new ObjectInputStream(
new FileInputStream( "oldmast.ser" ) );
inTransaction = new ObjectInputStream(
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
35
36
37
38
39
40
41
42
43
44
45
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
new FileInputStream( "trans.ser" ) );
outNewMaster = new ObjectOutputStream(
new FileOutputStream( "newmast.ser" ) );
logFile = new Formatter( "log.txt" );
} // end try
catch ( IOException io )
{
System.err.println( "Error opening the file." );
} // end catch
} // end method openFiles
public void processFiles()
{
int transactionAccountNumber;
int accountNumber;
try // block for reading/writing all records
{
// get a transaction record and its account number
transaction = getTransactionRecord();
// if the transaction is null, we are done
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
// get an account record and its account number
account = getAccountRecord();
// if the account is null, we are done
if ( account == null )
return;
accountNumber = account.getAccount();
while ( true )
{
while ( accountNumber < transactionAccountNumber )
{
// there is no transaction for this account
outNewMaster.writeObject( account );
account = getAccountRecord(); // get a new account
if ( account == null )
return;
accountNumber = account.getAccount();
} // end while
// if there is a transaction for this account
if ( accountNumber == transactionAccountNumber )
{
while ( accountNumber == transactionAccountNumber )
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
31
32
90
91
92
93
94
95
96
97
98
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
Chapter 14 Files and Streams
{
// combine the records
account.combine( transaction );
// get a new transaction
transaction = getTransactionRecord();
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
} // end while
// write them to the master file
outNewMaster.writeObject( account );
// get a new account
account = getAccountRecord();
if ( account == null )
return;
accountNumber = account.getAccount();
} // end if
while ( transactionAccountNumber < accountNumber )
{
// there is no account for this transaction
logFile.format( "%s %d\n",
"Unmatched transaction record for account number",
transactionAccountNumber );
// get a new transaction
transaction = getTransactionRecord();
if ( transaction == null )
return;
transactionAccountNumber = transaction.getAccount();
} // end while
} // end outer while
} // end try
catch ( IOException io )
{
System.err.println( "Error reading or writing the file." );
System.exit( 1 );
} // end catch
catch ( ClassNotFoundException noClass )
{
System.err.println( "Error reading the file." );
System.exit( 1 );
} // end catch
} // end method processFiles
public void closeFiles()
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
145
146
147
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
{
33
try // close the files
{
if ( inTransaction != null )
inTransaction.close();
if ( outNewMaster != null )
outNewMaster.close();
if ( inOldMaster != null )
inOldMaster.close();
if ( logFile != null )
logFile.close();
} // end try
catch ( IOException io )
{
System.err.println( "Error closing the file." );
System.exit( 1 );
} // end catch
} // end method closeFiles
// get a transaction record
private TransactionRecord getTransactionRecord()
throws IOException, ClassNotFoundException
{
TransactionRecord transaction;
try // try to read the record
{
transaction = ( TransactionRecord ) inTransaction.readObject();
} // end try
catch ( EOFException eof ) // if we hit end of transaction file
{
try
{
// read the remaining records from the old master
while ( true )
outNewMaster.writeObject( inOldMaster.readObject() );
} // end try
catch ( EOFException eof2 ) // we have hit end of old master file
{
return null;
} // end catch
} // end outer catch
// return a transaction if we successfully read it
return transaction;
} // end method getTransactionRecord
// get an account record
private AccountRecordSerializable getAccountRecord()
throws IOException, ClassNotFoundException
{
AccountRecordSerializable account;
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
34
Chapter 14 Files and Streams
200
201
// try to read an account record
202
try
203
{
204
account = ( AccountRecordSerializable ) inOldMaster.readObject();
205
} // end try
206
catch ( EOFException eof ) // we hit end of old master file
207
{
208
try
209
{
210
// all of these records are transactions without accounts
211
while ( true )
212
{
213
logFile.format( "%s %d\n",
214
"Unmatched transaction record for account number",
215
transaction.getAccount() );
216
transaction =
217
( TransactionRecord ) inTransaction.readObject();
218
} // end while
219
} // end try
220
catch ( EOFException eof2 ) // we hit end of transaction file
221
{
222
return null;
223
} // end catch
224
} // end outer catch
225
226
return account;
227
} // end method getAccountRecord
228 } // end class FileMatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Exercise 14.9 Solution: FileMatchTest.java
// Tests FileMatch program.
public class FileMatchTest
{
public static void main( String args[] )
{
FileMatch application = new FileMatch();
application.openFiles();
application.processFiles();
application.closeFiles();
} // end main
} // end class FileMatchTest
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
35
ANS: Contents of newmast.ser after FileMatchTest is executed.
100
300
500
700
Alan Jones 375.31
Mary Smith 79.30
Sam Sharp 0.00
Suzy Green -14.22
ANS: Contents of log.txt after FileMatchTest is executed.
Unmatched transaction record for account number 400
Unmatched transaction record for account number 900
14.10 (Student Poll) Figure 7.8 contains an array of survey responses that is hard coded into the
program. Suppose we wish to process survey results that are stored in a file. This exercise requires
two separate programs. First, create an application that prompts the user for survey responses and
outputs each response to a file. Use a Formatter to create a file called numbers.txt. Each integer
should be written using method format. Then modify the program of Fig. 7.8 to read the survey
responses from numbers.txt. The responses should be read from the file by using a Scanner. Method nextInt should be used to input one integer at a time from the file. The program should continue to read responses until it reaches the end of file. The results should be output to the text file
"output.txt".
ANS:
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
// Exercise 14.10 Solution: CreateResults.java
// Create poll results and output them to a file.
import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.IllegalFormatException;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class CreateResults
{
private int getValue()
{
int result = -1;
Scanner scanner = new Scanner( System.in );
// prompt the user for input
System.out.print(
"Enter integer result (1 - 10), -1 to quit: " );
try
{
result = scanner.nextInt();
} // end try
catch ( NoSuchElementException noSuchElementException )
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
36
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
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
Chapter 14 Files and Streams
{
System.err.println( "Error with input." );
System.exit( 1 );
} // end catch
return result;
} // end method getValue
private void outputData()
{
Formatter pollNumbers = null;
try
{
// create the output stream
pollNumbers = new Formatter( "numbers.txt" );
int pollValue = getValue(); // get a number from the user
// test for the sentinel value
while ( pollValue != -1 )
{
// if the number is valid
if ( pollValue > 0 && pollValue < 11 )
// write the value
pollNumbers.format( "%d\n", pollValue );
pollValue = getValue(); // get another value
} // end while
pollNumbers.close(); // close the file
} // end try
catch( SecurityException securityException )
{
System.err.println( "Error opening file." );
} // end catch
catch( FileNotFoundException fileNotFoundException )
{
System.err.println( "Output file cannot be found." );
} // end catch
catch( IllegalFormatException illegalFormatException )
{
System.err.println( "Error with the output's format." );
} // end catch
catch( FormatterClosedException formatterClosedException )
{
System.err.println( "File has been closed." );
} // end catch
finally
{
if ( pollNumbers != null )
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
78
79
80
81
82
83
84
85
86
87
pollNumbers.close();
} // end finally
} // end method outputData
public static void main( String args[] )
{
CreateResults application = new CreateResults();
application.outputData();
} // end main
} // end class CreateResults
ANS: Contents of numbers.txt after CreateResults.java has been executed:
3
4
5
2
2
2
8
8
9
9
9
9
9
5
7
7
7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Exercise 14.10 Solution: StudentPoll.java
// Read poll results from a file and output ratings.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.IllegalFormatException;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class StudentPoll
{
public void displayData()
{
int frequency[] = new int[ 11 ];
Formatter writer = null;
Scanner pollNumbers = null;
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
37
38
19
20
21
22
23
24
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Chapter 14 Files and Streams
try
{
pollNumbers = new Scanner(
new File( "numbers.txt" ) );
writer = new Formatter( "output.txt" );
writer.format( "%-12s%-12s\n", "Rating", "Frequency" );
// for each answer, use that value as subscript to
// determine element to increment
while ( pollNumbers.hasNext() )
++frequency[ pollNumbers.nextInt() ];
// append frequencies to String output
for ( int rating = 1; rating < frequency.length; rating++ )
writer.format( "%-12d%-12d\n", rating, frequency[ rating ] );
} // end try
catch ( FileNotFoundException fileNotFoundException )
{
System.err.println( "Error: Files cannot be opened." );
} // end catch
catch ( FormatterClosedException formatterClosedException )
{
System.err.println( "Error: Output file is closed." );
} // end catch
catch ( SecurityException securityException )
{
System.err.println( "Error opening file for writing." );
} // end catch
catch ( IllegalFormatException illegalFormatException )
{
System.err.println( "Error writing data to file." );
} // end catch
catch ( NoSuchElementException noSuchElementException )
{
System.err.println( "Error reading from file." );
} // end catch
catch ( IllegalStateException illegalStateException )
{
System.err.println( "Error: Input file is closed." );
} // end catch
finally
{
if ( writer != null )
writer.close();
if ( pollNumbers != null )
pollNumbers.close();
} // end finally
} // end displayData
} // end class StudentPoll
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
1
2
3
4
5
6
7
8
9
10
11
39
// Exercise 14.10 Solution: StudentPollTest.java
// Testing the StudentPoll class.
public class StudentPollTest
{
public static void main( String args[] )
{
StudentPoll application = new StudentPoll();
application.displayData();
} // end main
} // end class StudentPollTest
ANS: Contents of output.txt after StudentPollTest.java has been executed.
Rating
1
2
3
4
5
6
7
8
9
10
Frequency
0
3
1
1
2
0
3
2
5
0
14.11 Modify Exercise 11.18 to allow the user to save a drawing into a file or load a prior drawing
from a file using object serialization. Add buttons Load (to read objects from a file) and Save (to
write objects to a file). Use an ObjectOutputStream to write to the file and an ObjectInputStream
to read from the file. Write the array of MyShape objects using method writeObject (class ObjectOutputStream), and read the array using method readObject (ObjectInputStream). Note that
the object-serialization mechanism can read or write entire arrays—it is not necessary to manipulate
each element of the array of MyShape objects individually. It is simply required that all the shapes be
Serializable. Because the array of MyShape objects is of length 100 (and is not necessarily filled
with shapes drawn by the user), you may also want to store the number of shapes drawn to the file.
For both the Load and Save buttons, use a JFileChooser to allow the user to select the file in which
the shapes will be stored or from which they will be read. When the user first runs the program, no
shapes should be displayed on the screen. The user can display shapes by opening a previously saved
file of shapes or by drawing their own shapes. Once there are shapes on the screen, users can save
them to a file using the Save button.
ANS:
1
2
3
4
5
6
// Exercise 14.11: MyShape.java
// Declaration of class MyShape.
import java.awt.Color;
import java.awt.Graphics;
import java.io.Serializable;
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
40
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
52
53
54
55
56
57
58
59
60
61
Chapter 14 Files and Streams
public abstract class MyShape implements Serializable
{
private int x1; // x coordinate of first endpoint
private int y1; // y coordinate of first endpoint
private int x2; // x coordinate of second endpoint
private int y2; // y coordinate of second endpoint
private Color myColor; // color of this shape
// default constructor initializes values with 0
public MyShape()
{
this( 0, 0, 0, 0, Color.BLACK ); // call constructor to set values
} // end MyShape no-argument constructor
// constructor
public MyShape( int x1, int y1, int x2, int y2, Color color )
{
setX1( x1 ); // set x coordinate of first endpoint
setY1( y1 ); // set y coordinate of first endpoint
setX2( x2 ); // set x coordinate of second endpoint
setY2( y2 ); // set y coordinate of second endpoint
setColor( color ); // set the color
} // end MyShape constructor
// set the x-coordinate of the first point
public void setX1( int x1 )
{
this.x1 = ( x1 >= 0 ? x1 : 0 );
} // end method setX1
// get the x-coordinate of the first point
public int getX1()
{
return x1;
} // end method getX1
// set the x-coordinate of the second point
public void setX2( int x2 )
{
this.x2 = ( x2 >= 0 ? x2 : 0 );
} // end method setX2
// get the x-coordinate of the second point
public int getX2()
{
return x2;
} // end method getX2
// set the y-coordinate of the first point
public void setY1( int y1 )
{
this.y1 = ( y1 >= 0 ? y1 : 0 );
} // end method setY1
// get the y-coordinate of the first point
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public int getY1()
{
return y1;
} // end method getY1
// set the y-coordinate of the second point
public void setY2( int y2 )
{
this.y2 = ( y2 >= 0 ? y2 : 0 );
} // end method setY2
// get the y-coordinate of the second point
public int getY2()
{
return y2;
} // end method getY2
// set the color
public void setColor( Color color )
{
myColor = color;
} // end method setColor
// get the color
public Color getColor()
{
return myColor;
} // end method getColor
// abstract draw method
public abstract void draw( Graphics g );
} // end class MyShape
// Exercise 14.11: MyLine.java
// Declaration of class MyLine.
import java.awt.Color;
import java.awt.Graphics;
public class MyLine extends MyShape
{
// call default superclass constructor
public MyLine()
{
super();
} // end MyLine no-argument constructor
// call superclass constructor passing parameters
public MyLine( int x1, int y1, int x2, int y2, Color color )
{
super( x1, y1, x2, y2, color );
} // end MyLine constructor
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
41
42
Chapter 14 Files and Streams
20
21
22
23
24
25
26
// draw line in specified color
public void draw( Graphics g )
{
g.setColor( getColor() );
g.drawLine( getX1(), getY1(), getX2(), getY2() );
} // end method draw
} // end class MyLine
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Exercise 14.11: MyBoundedShape.java
// Declaration of class MyBoundedShape.
import java.awt.Color;
import java.awt.Graphics;
public abstract class MyBoundedShape extends MyShape
{
private boolean filled; // whether this shape is filled
// call default superclass constructor
public MyBoundedShape()
{
super();
setFilled( false );
} // end MyBoundedShape no-argument constructor
// call superclass constructor passing parameters
public MyBoundedShape( int x1, int y1, int x2, int y2,
Color color, boolean isFilled )
{
super( x1, y1, x2, y2, color );
setFilled( isFilled );
} // end MyBoundedShape constructor
// get upper left x coordinate
public int getUpperLeftX()
{
return Math.min( getX1(), getX2() );
} // end method getUpperLeftX
// get upper left y coordinate
public int getUpperLeftY()
{
return Math.min( getY1(), getY2() );
} // end method getUpperLeftY
// get shape width
public int getWidth()
{
return Math.abs( getX2() - getX1() );
} // end method getWidth
// get shape height
public int getHeight()
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
28
29
30
31
32
33
{
return Math.abs( getY2() - getY1() );
} // end method getHeight
// determines whether this shape is filled
public boolean isFilled()
{
return filled;
} // end method is filled
// sets whether this shape is filled
public void setFilled( boolean isFilled )
{
filled = isFilled;
} // end method setFilled
} // end class MyBoundedShape
// Exercise 14.11: MyRect.java
// Declaration of class MyRect.
import java.awt.Color;
import java.awt.Graphics;
public class MyRect extends MyBoundedShape
{
// call default superclass constructor
public MyRect()
{
super();
} // end MyRect no-argument constructor
// call superclass constructor passing parameters
public MyRect( int x1, int y1, int x2, int y2,
Color color, boolean isFilled )
{
super( x1, y1, x2, y2, color, isFilled );
} // end MyRect constructor
// draw rectangle
public void draw( Graphics g )
{
g.setColor( getColor() );
if ( isFilled() )
g.fillRect( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
else
g.drawRect( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
} // end method draw
} // end class MyRect
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
43
44
Chapter 14 Files and Streams
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
28
29
30
31
32
33
// Exercise 14.11: MyOval.java
// Declaration of class MyOval.
import java.awt.Color;
import java.awt.Graphics;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Exercise 14.11: DrawPanel.java
// JPanel that allows the user to draw shapes with the mouse.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
public class MyOval extends MyBoundedShape
{
// call default superclass constructor
public MyOval()
{
super();
} // end MyOval no-argument constructor
// call superclass constructor passing parameters
public MyOval( int x1, int y1, int x2, int y2,
Color color, boolean isFilled )
{
super( x1, y1, x2, y2, color, isFilled );
} // end MyOval constructor
// draw oval
public void draw( Graphics g )
{
g.setColor( getColor() );
if ( isFilled() )
g.fillOval( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
else
g.drawOval( getUpperLeftX(), getUpperLeftY(),
getWidth(), getHeight() );
} // end method draw
} // end class MyOval
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
17
18
19
20
21
22
23
24
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class DrawPanel extends JPanel
{
private MyShape shapes[]; // array containing all the shapes
private int shapeCount; // statistic on the number of each shape
private
private
private
private
int shapeType; // the type of shape to draw
MyShape currentShape; // the current shape being drawn
Color currentColor; // the color of the shape
boolean filledShape; // whether this shape is filled
private JLabel statusLabel; // label displaying mouse coordinates
// constructor
public DrawPanel( JLabel status )
{
shapes = new MyShape[ 100 ]; // create the array
shapeCount = 0; // initially we have no shapes
setShapeType( 0 ); // initially draw lines
setDrawingColor( Color.BLACK ); // start drawing with black
setFilledShape( false );// not filled by default
currentShape = null; // not drawing anything initially
setBackground( Color.WHITE ); // set a white background
// add the mouse listeners
MouseHandler mouseHandler = new MouseHandler();
addMouseListener( mouseHandler );
addMouseMotionListener( mouseHandler );
// set the status label for displaying mouse coordinates
statusLabel = status;
} // end DrawPanel constructor
// draw shapes using polymorphism
public void paintComponent( Graphics g )
{
super.paintComponent( g );
for ( int i = 0; i < shapeCount; i++ )
shapes[ i ].draw( g );
if ( currentShape != null )
currentShape.draw( g );
} // end method paintComponent
// sets the type of shape to draw
public void setShapeType( int shapeType )
{
if ( shapeType < 0 || shapeType > 2 )
shapeType = 0;
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
45
46
72
73
74
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
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
Chapter 14 Files and Streams
this.shapeType = shapeType;
} // end method setShapeType
// sets the drawing color
public void setDrawingColor( Color c )
{
currentColor = c;
} // end method setDrawingColor
// clears the last shape drawn
public void clearLastShape()
{
if ( shapeCount > 0 )
{
shapeCount--;
repaint();
} // end if
} // end method clearLastShape
// clears all drawings on this panel
public void clearDrawing()
{
shapeCount = 0;
repaint();
} // end method clearDrawing
// sets whether to draw a filled shape
public void setFilledShape( boolean isFilled )
{
filledShape = isFilled;
} // end method setFilledShape
// load saved drawing
public void loadDrawing()
{
ObjectInputStream input = null;
try // user selects file, shapes are input
{
// use JFileChooser to select file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(
JFileChooser.FILES_ONLY );
int result = fileChooser.showOpenDialog(
DrawPanel.this );
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
// get selected file
File fileName = fileChooser.getSelectedFile();
// display error if invalid
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
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
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
180
181
if ( ( fileName == null ) ||
( fileName.getName().equals( "" ) ) )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"Invalid File Name", "Invalid File Name",
JOptionPane.ERROR_MESSAGE );
return;
} // end if
// open file for input
input = new ObjectInputStream(
new FileInputStream( fileName ) );
// read in number of shapes using deserialization
shapeCount = ( Integer ) input.readObject();
// read in shapes using deserialization
// set shapes to be displayed on drawPanel
shapes = ( MyShape [] ) input.readObject();
repaint(); // redraw shapes
} // end try
catch ( EOFException eofException )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"No more records in file.", "End of File",
JOptionPane.ERROR_MESSAGE );
} // end catch
catch ( ClassNotFoundException classNotFoundException )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"Unable to create object.", "Class Not Found",
JOptionPane.ERROR_MESSAGE );
} // end catch
catch ( IOException ioException )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"Error opening file.", "Error",
JOptionPane.ERROR_MESSAGE );
} // end catch
finally
{
try
{
if ( input != null )
input.close(); // close file and stream
} // end try
catch ( IOException ioException )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"Error closing file.", "Error",
JOptionPane.ERROR_MESSAGE );
} // end catch
} // end finally
} // end method loadDrawing
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
47
48
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
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
232
233
234
235
236
237
Chapter 14 Files and Streams
// save drawing as serialized objects
public void saveDrawing()
{
ObjectOutputStream output = null;
try
{
// use JFileChooser to select file
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(
JFileChooser.FILES_ONLY );
int result = fileChooser.showSaveDialog(
DrawPanel.this );
// if user clicked Cancel button on dialog, return
if ( result == JFileChooser.CANCEL_OPTION )
return;
// get selected file
File fileName = fileChooser.getSelectedFile();
// display error if invalid
if ( ( fileName == null ) ||
( fileName.getName().equals( "" ) ) )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"Invalid File Name", "Invalid File Name",
JOptionPane.ERROR_MESSAGE );
return;
} // end if
// open file for output
output = new ObjectOutputStream(
new FileOutputStream( fileName ) );
// write number of shapes to file
output.writeObject( shapeCount );
// write shapes to file using serialization
output.writeObject( shapes );
} // end try
catch ( IOException ioException )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"Error Opening File", "Error.",
JOptionPane.ERROR_MESSAGE );
} // end catch
finally
{
try
{
if ( output != null )
output.close(); // close file and stream
} // end try
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
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
284
285
286
287
288
289
290
291
292
catch ( IOException ioException )
{
JOptionPane.showMessageDialog( DrawPanel.this,
"Error closing file.", "Error",
JOptionPane.ERROR_MESSAGE );
} // end catch
} // end finally
} // end method saveDrawing
// Handles mouse events for this JPanel
private class MouseHandler extends MouseAdapter
implements MouseMotionListener
{
// creates and sets the initial position for the new shape
public void mousePressed( MouseEvent e )
{
if ( currentShape != null )
return;
// create the appropriate shape based on shapeType
switch ( shapeType )
{
case 0:
currentShape = new MyLine( e.getX(), e.getY(),
e.getX(), e.getY(), currentColor );
break;
case 1:
currentShape = new MyOval( e.getX(), e.getY(),
e.getX(), e.getY(), currentColor, filledShape );
break;
case 2:
currentShape = new MyRect( e.getX(), e.getY(),
e.getX(), e.getY(), currentColor, filledShape );
break;
} // end switch
} // end method mousePressed
// fixes the current shape onto the panel
public void mouseReleased( MouseEvent e )
{
if ( currentShape == null )
return;
// set the second point on the shape
currentShape.setX2( e.getX() );
currentShape.setY2( e.getY() );
// only set the shape if there is room in the array
if ( shapeCount < shapes.length )
{
shapes[ shapeCount ] = currentShape;
shapeCount++;
} // end if
currentShape = null; // clear the temporary drawing shape
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
49
50
Chapter 14 Files and Streams
293
repaint();
294
} // end method mouseReleased
295
296
// update the shape to the current mouse position while dragging
297
public void mouseDragged( MouseEvent e )
298
{
299
if ( currentShape != null )
300
{
301
currentShape.setX2( e.getX() );
302
currentShape.setY2( e.getY() );
303
repaint();
304
} // end if
305
306
mouseMoved( e ); // update status bar
307
} // end method mouseDragged
308
309
// updates the status bar to show the current mouse coordinates
310
public void mouseMoved( MouseEvent e )
311
{
312
statusLabel.setText(
313
String.format( "(%d,%d)", e.getX(), e.getY() ) );
314
} // end method mouseMoved
315
} // end class MouseHandler
316 } // end class DrawPanel
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
// Exercise 14.11: DrawFrame.java
// Program that creates a panel for the user to draw shapes.
// Allows the user to choose the shape and color.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class DrawFrame extends JFrame
implements ItemListener, ActionListener
{
// Array of possible colors
private Color colors[] = { Color.BLACK, Color.BLUE, Color.CYAN,
Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY,
Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE,
Color.YELLOW };
// Array of names corresponding to the possible colors
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
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
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
81
82
51
private String colorNames[] = { "Black", "Blue", "Cyan", "Dark Gray",
"Gray", "Green", "Light Gray", "Magenta", "Orange", "Pink", "Red",
"White", "Yellow" };
// Array of possible shapes
private String shapes[] = { "Line", "Oval", "Rectangle" };
private DrawPanel drawPanel; // panel that handles the drawing
private
private
private
private
private
private
private
JButton loadButton; // button to load saved drawing
JButton saveButton; // button to save drawing to file
JButton undoButton; // button to undo the last shape drawn
JButton clearButton; // button to clear all shapes
JComboBox colorChoices; // combo box for selecting the color
JComboBox shapeChoices; // combo box for selecting shapes
JCheckBox filledCheckBox; // check box to toggle filled shapes
// constructor
public DrawFrame()
{
super( "Java Drawings" );
// create a panel to store the components at the top of the frame
JPanel topPanel = new JPanel( new FlowLayout() );
// create a button for loading a saved drawing
loadButton = new JButton( "Load" );
loadButton.addActionListener( this );
topPanel.add( loadButton );
// create a button for saving drawing
saveButton = new JButton( "Save" );
saveButton.addActionListener( this );
topPanel.add( saveButton );
// create a button for clearing the last drawing
undoButton = new JButton( "Undo" );
undoButton.addActionListener( this );
topPanel.add( undoButton );
// create a button for clearing all drawings
clearButton = new JButton( "Clear" );
clearButton.addActionListener( this );
topPanel.add( clearButton );
// create a combo-box for choosing colors
colorChoices = new JComboBox( colorNames );
colorChoices.addItemListener( this );
topPanel.add( colorChoices );
// create a combo-box for choosing shapes
shapeChoices = new JComboBox( shapes );
shapeChoices.addItemListener( this );
topPanel.add( shapeChoices );
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
52
Chapter 14 Files and Streams
83
// create a check-box to determine whether the shape is filled
84
filledCheckBox = new JCheckBox( "Filled" );
85
filledCheckBox.addItemListener( this );
86
topPanel.add( filledCheckBox );
87
88
// add the top panel to the frame
89
add( topPanel, BorderLayout.NORTH );
90
91
// create a label for the status bar
92
JLabel statusLabel = new JLabel( "(0,0)" );
93
94
// add the status bar at the bottom
95
add( statusLabel, BorderLayout.SOUTH );
96
97
// create the DrawPanel with its status bar label
98
drawPanel = new DrawPanel( statusLabel );
99
100
add( drawPanel ); // add the drawing area to the center
101
} // end DrawFrame constructor
102
103
// handle selections made to a combo box of check box
104
public void itemStateChanged( ItemEvent e )
105
{
106
if ( e.getSource() == shapeChoices ) // choosing a shape
107
drawPanel.setShapeType( shapeChoices.getSelectedIndex() );
108
else if (e.getSource() == colorChoices ) // choosing a color
109
drawPanel.setDrawingColor(
110
colors[ colorChoices.getSelectedIndex() ] );
111
else if ( e.getSource() == filledCheckBox ) // filled/unfilled
112
drawPanel.setFilledShape( filledCheckBox.isSelected() );
113
} // end method itemStateChanged
114
115
// handle button clicks
116
public void actionPerformed( ActionEvent e )
117
{
118
if ( e.getSource() == loadButton )
119
drawPanel.loadDrawing();
120
else if ( e.getSource() == saveButton )
121
drawPanel.saveDrawing();
122
else if ( e.getSource() == undoButton )
123
drawPanel.clearLastShape();
124
else if ( e.getSource() == clearButton )
125
drawPanel.clearDrawing();
126
} // end method actionPerformed
127 } // end class DrawFrame
1
2
3
4
5
6
// Exercise 14.11: TestDraw.java
// Test application to display a DrawFrame
import javax.swing.JFrame;
public class TestDraw
{
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
7
8
9
10
11
12
13
14
public static void main( String args[] )
{
DrawFrame application = new DrawFrame();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
application.setSize( 600, 500 );
application.setVisible( true );
} // end main
} // end class TestDraw
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
53
54
Chapter 14 Files and Streams
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
Exercises
© Copyright 1992-2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.
55
Related documents