Sequential-Access Text Files

In this section, we create and manipulate sequential-access files. As mentioned earlier, these are files in which records are stored in order by the record-key field. We first demonstrate sequential-access files using text files, allowing the reader to quickly create and edit human-readable files. In the subsections of this chapter we discuss creating, writing data to, reading data from and updating sequential-access text files. We also include a credit-inquiry program that retrieves specific data from a file.

14.5.1. Creating a Sequential-Access Text File

Java imposes no structure on a filenotions such as a record do not exist as part of the Java language. Therefore, the programmer must structure files to meet the requirements of the intended application. In the following example, we see how to impose a record structure on a file.

The program in Fig. 14.6Fig. 14.7 and Fig. 14.9 creates a simple sequential-access file that might be used in an accounts receivable system to help keep track of the amounts owed to a company by its credit clients. For each client, the program obtains from the user an account number, the client's name and the client's balance (i.e., the amount the client owes the company for goods and services received). The data obtained for each client constitutes a "record" for that client. The account number is used as the record key in this applicationthe file will be created and maintained in account number order. The program assumes that the user enters the records in account number order. In a comprehensive accounts receivable system (based on sequential-access files), a sorting capability would be provided so that the user could enter the records in any order. The records would then be sorted and written to the file.

Figure 14.6. AccountRecord maintains information for one account.

(This item is displayed on pages 683 - 684 in the print version)

 1 // Fig. 14.6: AccountRecord.java
 2 // A class that represents one record of information.
 3 package com.deitel.jhtp6.ch14; // packaged for reuse
 4
 5 public class AccountRecord
 6 {
 7 private int account;
 8 private String firstName;
 9 private String lastName;
10 private double balance;
11
12 // no-argument constructor calls other constructor with default values
13 public AccountRecord()
14 {
15 this ( 0, "", "", 0.0 ); // call four-argument constructor
16 } // end no-argument AccountRecord constructor
17
18 // initialize a record
19 public AccountRecord( int acct, String first, String last, double bal )
20 {
21 setAccount( acct );
22 setFirstName( first );
23 setLastName( last );
24 setBalance( bal );
25 } // end four-argument AccountRecord constructor
26
27 // set account number
28 public void setAccount( int acct )
29 {
30 account = acct;
31 } // end method setAccount
32
33 // get account number
34 public int getAccount()
35 {
36 return account;
37 } // end method getAccount
38
39 // set first name
40 public void setFirstName( String first )
41 {
42 firstName = first;
43 } // end method setFirstName
44
45 // get first name
46 public String getFirstName()
47 {
48 return firstName;
49 } // end method getFirstName
50
51 // set last name
52 public void setLastName( String last )
53 {
54 lastName = last;
55 } // end method setLastName
56
57 // get last name
58 public String getLastName()
59 {
60 return lastName;
61 } // end method getLastName
62
63 // set balance
64 public void setBalance( double bal )
65 {
66 balance = bal;
67 } // end method setBalance
68
69 // get balance
70 public double getBalance()
71 {
72 return balance;
73 } // end method getBalance
74 } // end class AccountRecord

Figure 14.7. Creating a sequential text file.

(This item is displayed on pages 686 - 687 in the print version)

 1 // Fig. 14.7: CreateTextFile.java
 2 // Writing data to a text file with class Formatter.
 3 import java.io.FileNotFoundException; 
 4 import java.lang.SecurityException; 
 5 import java.util.Formatter; 
 6 import java.util.FormatterClosedException;
 7 import java.util.NoSuchElementException; 
 8 import java.util.Scanner; 
 9
10 import com.deitel.jhtp6.ch14.AccountRecord;
11
12 public class CreateTextFile
13 {
14 private Formatter output; // object used to output text to file
15
16 // enable user to open file
17 public void openFile()
18 {
19 try
20 {
21 output = new Formatter( "clients.txt" );
22 } // end try
23 catch ( SecurityException securityException )
24 {
25 System.err.println(
26 "You do not have write access to this file." );
27 System.exit( 1 );
28 } // end catch
29 catch ( FileNotFoundException filesNotFoundException )
30 {
31 System.err.println( "Error creating file." );
32 System.exit( 1 );
33 } // end catch
34 } // end method openFile
35
36 // add records to file
37 public void addRecords()
38 {
39 // object to be written to file
40 AccountRecord record = new AccountRecord();
41
42 Scanner input = new Scanner( System.in );
43
44 System.out.printf( "%s
%s
%s
%s

",
45 "To terminate input, type the end-of-file indicator ",
46 "when you are prompted to enter input.",
47 "On UNIX/Linux/Mac OS X type  d then press Enter",
48 "On Windows type  z then press Enter" );
49
50 System.out.printf( "%s
%s",
51 "Enter account number (> 0), first name, last name and balance.",
52 "? " );
53
54 while ( input.hasNext() ) // loop until end-of-file indicator
55 {
56 try // output values to file
57 {
58 // retrieve data to be output
59 record.setAccount( input.nextInt() ); // read account number
60 record.setFirstName( input.next() ); // read first name 
61 record.setLastName( input.next() ); // read last name 
62 record.setBalance( input.nextDouble() ); // read balance 
63
64 if ( record.getAccount() > 0 )
65 {
66 // write new record
67 output.format( "%d %s %s %.2f
", record.getAccount(),
68  record.getFirstName(), record.getLastName(), 
69  record.getBalance() ); 
70 } // end if
71 else
72 {
73 System.out.println(
74 "Account number must be greater than 0." );
75 } // end else
76 } // end try
77 catch ( FormatterClosedException formatterClosedException )
78 {
79 System.err.println( "Error writing to file." );
80 return;
81 } // end catch
82 catch ( NoSuchElementException elementException )
83 {
84 System.err.println( "Invalid input. Please try again." );
85 input.nextLine(); // discard input so user can try again
86 } // end catch
87
88 System.out.printf( "%s %s
%s", "Enter account number (>0),",
89 "first name, last name and balance.", "? " );
90 } // end while
91 } // end method addRecords
92
93 // close file
94 public void closeFile()
95 {
96 if ( output != null )
97 output.close();
98 } // end method closeFile
99 } // end class CreateTextFile

Class AccountRecord (Fig. 14.6) encapsulates the client record information (i.e., account, first name, etc.) used by the examples in this chapter. The class AccountRecord is declared in package com.deitel.jhtp6.ch14 (line 3), so that it can be imported into several examples. Class AccountRecord contains private data members account, firstName, lastName and balance (lines 710). This class also provides public set and get methods for accessing the private fields.

Compile class AccountRecord as follows:

 javac -d c:examplesch14 comdeiteljhtp6ch14AccountRecord.java

This places AccountRecord.class in its package directory structure and places the package in c:examplesch14. When you compile class AccountRecord (or any other classes that will be reused in this chapter), you should place them in a common directory (e.g., c:examplesch14). When you compile or execute classes that use AccountRecord (e.g., CreateTextFile in Fig. 14.7), you must specify the command-line argument - classpath to both javac and java, as in

 javac -classpath .;c:examplesch14 CreateTextFile.java
 java -classpath .;c:examplesch14 CreateTextFile

Note that the current directory (specified with .) is included in the classpath. This ensures that the compiler can locate other classes in the same directory as the class being compiled. The path separator used in the preceding commands should be the one that is appropriate for your platformfor example, a semicolon (;) on Windows and a colon (:) on UNIX/ Linux/Mac OS X.

Now let us examine class CreateTextFile (Fig. 14.7). Line 14 declares Formatter variable output. As discussed in Section 14.3, a Formatter object outputs formatted strings, using the same formatting capabilities as method System.out.printf. A Formatter object can output to various locations, such as the screen or a file, as is done here. The Formatter object is instantiated in line 21 in method openFile (lines 1734). The constructor used in line 21 takes one argumenta String containing the name of the file, including its path. If a path is not specified, as is the case here, the JVM assumes that the files is in the directory from which the program was executed. For text files, we use the .txt file extension. If the file does not exist, it will be created. If an existing file is opened, the contents of the file are truncatedall the data in the file is discarded. At this point the file is open for writing, and the resulting Formatter object can be used to write data to the file. Lines 2328 handle the SecurityException, which occurs if the user does not have permission to write data to the file. Lines 2933 handle the FileNotFoundException, which occurs if the file does not exist and a new file cannot be created. This exception may also occur if there is an error opening the file. Note that in both exception handlers, we call static method System.exit, and pass the value 1. This method terminates the application. An argument of 0 to method exit indicates successful program termination. A nonzero value, such as 1 in this example, normally indicates that an error has occurred. This value is passed to the command window that executed the program. The argument is useful if the program is executed from a batch file on Windows systems or a shell script on UNIX/Linux/Mac OS X systems. Batch files and shell scripts offer a convenient way of executing several programs in sequence. When the first program ends, the next program begins execution. It is possible to use the argument to method exit in a batch file or shell script to determine whether other programs should execute. For more information on batch files or shell scripts, see your operating system's documentation.

Method addRecords (lines 3791) prompts the user to enter the various fields for each record or to enter the end-of-file key sequence when data entry is complete. Figure 14.8 lists the key combinations for entering end-of-file for various computer systems.

Figure 14.8. End-of-file key combinations for various popular operating systems.

(This item is displayed on page 688 in the print version)

Operating system

Key combination

UNIX/Linux/Mac OS X

d

Windows

z

Line 40 creates an AccountRecord object, which will be used to store the values of the current record entered by the user. Line 42 creates a Scanner object to read input from the user at the keyboard. Lines 4448 and 5052 prompt the user for input.

Line 54 uses Scanner method hasNext to determine whether the end-of-file key combination has been entered. The loop executes until hasNext encounters the end-of-file indicators.

Lines 5962 read data from the user, storing the record information in the AccountRecord object. Each statement throws a NoSuchElementException (handled in lines 8286) if the data is in the wrong format (e.g., a string when an int is expected) or if there is no more data to input. If the account number is greater than 0 (line 64), the record's information is written to clients.txt (lines 6769) using method format. This method can perform identical formatting to the System.out.printf method used extensively in earlier chapters. This method outputs a formatted string to the output destination of the Formatter object, in this case the file clients.txt. The format string "%d %s %s %.2 " indicates that the current record will be stored as an integer (the account number) followed by a string (the first name), another string (the last name) and a floating-point value (the balance). Each piece of information is separated from the next by a space and the double value (the balance) is output with two digits to the right of the decimal point. The data in the text file can be viewed with a text editor, or retrieved later by a program designed to read the file (Section 14.5.2). When lines 6769 execute, if the Formatter object is closed, a FormatterClosedException will be thrown (handled in lines 7781). [Note: You can also output data to a text file using class java.io.PrintWriter, which also provides method format for outputting formatted data.]

Lines 9498 declare method closeFile, which closes the Formatter and the underlying output file. Line 97 closes the object by simply calling method close. If method close is not called explicitly, the operating system normally will close the file when program execution terminates. This is an example of operating system "housekeeping."

Figure 14.9 runs the program. Line 8 creates a CreateTextFile object, which is then used to open, add records to and close the file (lines 1012). The sample data for this application is shown in Fig. 14.10. In the sample execution for this program, the user enters information for five accounts, then enters end-of-file to signal that data entry is complete. The sample execution does not show how the data records actually appear in the file. In the next section to verify that the file has been created successfully, we present a program that reads the file and prints its contents. Because this is a text file, you can also verify the information by opening the file in a text editor.

Figure 14.9. Testing the CreateTextFile class.

(This item is displayed on page 689 in the print version)

 1 // Fig. 14.9: CreateTextFileTest.java
 2 // Testing the CreateTextFile class.
 3
 4 public class CreateTextFileTest
 5 {
 6 public static void main( String args[] )
 7 {
 8 CreateTextFile application = new CreateTextFile();
 9
10 application.openFile();
11 application.addRecords();
12 application.closeFile();
13 } // end main
14 } // end class CreateTextFileTest
 
To terminate input, type the end-of-file indicator
when you are prompted to enter input.
On UNIX/Linux/Mac OS X type  d then press Enter
On Windows type  z then press Enter

Enter account number (> 0), first name, last name and balance.
? 100 Bob Jones 24.98
Enter account number (> 0), first name, last name and balance.
? 200 Steve Doe -345.67
Enter account number (> 0), first name, last name and balance.
? 300 Pam White 0.00
Enter account number (> 0), first name, last name and balance.
? 400 Sam Stone -42.16
Enter account number (> 0), first name, last name and balance.
? 500 Sue Rich 224.62
Enter account number (> 0), first name, last name and balance.
?^Z
 

Figure 14.10. Sample data for the program in Fig. 14.7.

(This item is displayed on page 689 in the print version)

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

 

14.5.2. Reading Data from a Sequential-Access Text File

Data is stored in files so that it may be retrieved for processing when needed. Section 14.5.1 demonstrated how to create a file for sequential access. This section shows how to read data sequentially from a text file. In this section, we demonstrate how class Scanner can be used to input data from a file rather than the keyboard.

The application in Fig. 14.11 and Fig. 14.12 reads records from the file "clients. txt" created by the application of Section 14.5.1 and displays the record contents. Line 13 of Fig. 14.11 declares a Scanner that will be used to retrieve input from the file.

Figure 14.11. Sequential file reading using a Scanner.

(This item is displayed on pages 690 - 691 in the print version)

 1 // Fig. 14.11: ReadTextFile.java
 2 // This program reads a text file and displays each record.
 3 import java.io.File;
 4 import java.io.FileNotFoundException;
 5 import java.lang.IllegalStateException;
 6 import java.util.NoSuchElementException;
 7 import java.util.Scanner;
 8
 9 import com.deitel.jhtp6.ch14.AccountRecord;
10
11 public class ReadTextFile
12 {
13 private Scanner input;
14
15 // enable user to open file
16 public void openFile()
17 {
18 try
19 {
20 input = new Scanner( new File( "clients.txt" ) );
21 } // end try
22 catch ( FileNotFoundException fileNotFoundException )
23 {
24 System.err.println( "Error opening file." );
25 System.exit( 1 );
26 } // end catch
27 } // end method openFile
28
29 // read record from file
30 public void readRecords()
31 {
32 // object to be written to screen
33 AccountRecord record = new AccountRecord();
34
35 System.out.printf( "%-10s%-12s%-12s%10s
", "Account",
36 "First Name", "Last Name", "Balance" );
37
38 try // read records from file using Scanner object
39 {
40 while ( input.hasNext() )
41 {
42 record.setAccount( input.nextInt() ); // read account number
43 record.setFirstName( input.next() ); // read first name 
44 record.setLastName( input.next() ); // read last name 
45 record.setBalance( input.nextDouble() ); // read balance 
46
47 // display record contents 
48 System.out.printf( "%-10d%-12s%-12s%10.2f
", 
49  record.getAccount(), record.getFirstName(), 
50  record.getLastName(), record.getBalance() );
51 } // end while
52 } // end try
53 catch ( NoSuchElementException elementException )
54 {
55 System.err.println( "File improperly formed." );
56 input.close();
57 System.exit( 1 );
58 } // end catch
59 catch ( IllegalStateException stateException )
60 {
61 System.err.println( "Error reading from file." );
62 System.exit( 1 );
63 } // end catch
64 } // end method readRecords
65
66 // close file and terminate application
67 public void closeFile()
68 {
69 if ( input != null )
70 input.close(); // close file
71 } // end method closeFile
72 } // end class ReadTextFile

Figure 14.12. Testing the ReadTextFile class.

(This item is displayed on page 691 in the print version)

 1 // Fig. 14.12: ReadTextFileTest.java
 2 // This program test class ReadTextFile.
 3
 4 public class ReadTextFileTest
 5 {
 6 public static void main( String args[] )
 7 {
 8 ReadTextFile application = new ReadTextFile();
 9
10 application.openFile();
11 application.readRecords();
12 application.closeFile();
13 } // end main
14 } // end class ReadTextFileTest
 
Account First Name Last Name Balance
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
 

Method openFile (lines 1627) opens the file for reading by instantiating a Scanner object in line 20. We pass a File object to the constructor, which specifies that the Scanner object will read from the file "clients.txt" located in the directory from which the application executes. If the file cannot be found, a FileNotFoundException occurs. The exception is handled in lines 2226.

Method readRecords (lines 3064) reads and displays records from the file. Line 33 creates AccountRecord object record to store the current record's information. Lines 3536 display headers for the columns in the application's output. Lines 4051 read data from the file until the end-of-file marker is reached (in which case, method hasNext will return false at line 40). Lines 4245 use Scanner methods nextInt, next and nexTDouble to input an integer (the account number), two strings (the first and last names) and a double value (the balance). Each record is one line of data in the file. The values are stored in object record. If the information in the file is not properly formed (e.g., there is a last name where there should be a balance), a NoSuchElementException occurs when the record is input. This exception is handled in lines 5358. If the Scanner was closed before the data was input, an IllegalStateException occurs (handled in lines 5963). If no exceptions occur, the record's information is displayed on the screen (lines 4850). Note in the format string in line 48 that the account number, first name and last name are left justified, while the balance is right justified and output with two digits of precision. Each iteration of the loop inputs one line of text from the text file, which represents one record.

Lines 6771 define method closeFile, which closes the Scanner. Method main is defined in Fig. 14.12, in lines 613. Line 8 creates a ReadTextFile object, which is then used to open, add records to and close the file (lines 1012).

14.5.3. Case Study: A Credit-Inquiry Program

To retrieve data sequentially from a file, programs normally start reading from the beginning of the file and read all the data consecutively until the desired information is found. It might be necessary to process the file sequentially several times (from the beginning of the file) during the execution of a program. Class Scanner does not provide the ability to reposition to the beginning of the file. If it is necessary to read the file again, the program must close the file and reopen it.

The program in Fig. 14.13Fig. 14.15 allows a credit manager to obtain lists of customers with zero balances (i.e., customers who do not owe any money), customers with credit balances (i.e., customers to whom the company owes money) and customers with debit balances (i.e., customers who owe the company money for goods and services received). A credit balance is a negative amount, and a debit balance is a positive amount.

Figure 14.13. Enumeration for menu options.

 1 // Fig. 14.13: MenuOption.java
 2 // Defines an enum type for the credit inquiry program's options.
 3
 4 public enum MenuOption
 5 {
 6 // declare contents of enum type
 7 ZERO_BALANCE( 1 ),
 8 CREDIT_BALANCE( 2 ),
 9 DEBIT_BALANCE( 3 ),
10 END( 4 );
11
12 private final int value; // current menu option
13
14 MenuOption( int valueOption )
15 {
16 value = valueOption;
17 } // end MenuOptions enum constructor
18
19 public int getValue()
20 {
21 return value;
22 } // end method getValue
23 } // end enum MenuOption

Figure 14.14. Credit-inquiry program.

(This item is displayed on pages 693 - 695 in the print version)

 1 // Fig. 14.14: CreditInquiry.java
 2 // This program reads a file sequentially and displays the
 3 // contents based on the type of account the user requests
 4 // (credit balance, debit balance or zero balance).
 5 import java.io.File;
 6 import java.io.FileNotFoundException;
 7 import java.lang.IllegalStateException;
 8 import java.util.NoSuchElementException;
 9 import java.util.Scanner;
10
11 import com.deitel.jhtp6.ch14.AccountRecord;
12 
13 public class CreditInquiry
14 {
15 private MenuOption accountType;
16 private Scanner input;
17 private MenuOption choices[] = { MenuOption.ZERO_BALANCE,
18 MenuOption.CREDIT_BALANCE, MenuOption.DEBIT_BALANCE,
19 MenuOption.END };
20 
21 // read records from file and display only records of appropriate type
22 private void readRecords()
23 {
24 // object to be written to file
25 AccountRecord record = new AccountRecord();
26 
27 try // read records
28 {
29 // open file to read from beginning
30 input = new Scanner( new File( "clients.txt" ) );
31 
32 while ( input.hasNext() ) // input the values from the file
33 {
34 record.setAccount( input.nextInt() ); // read account number
35 record.setFirstName( input.next() ); // read first name 
36 record.setLastName( input.next() ); // read last name 
37 record.setBalance( input.nextDouble() ); // read balance 
38 
39 // if proper acount type, display record
40 if ( shouldDisplay( record.getBalance() ) ) 
41  System.out.printf( "%-10d%-12s%-12s%10.2f
", 
42  record.getAccount(), record.getFirstName(), 
43  record.getLastName(), record.getBalance() );
44 } // end while
45 } // end try
46 catch ( NoSuchElementException elementException )
47 {
48 System.err.println( "File improperly formed." );
49 input.close();
50 System.exit( 1 );
51 } // end catch
52 catch ( IllegalStateException stateException )
53 {
54 System.err.println( "Error reading from file." );
55 System.exit( 1 );
56 } // end catch
57 catch ( FileNotFoundException fileNotFoundException )
58 {
59 System.err.println( "File cannot be found." );
60 System.exit( 1 );
61 } // end catch
62 finally
63 {
64 if ( input != null )
65 input.close(); // close the Scanner and the file
66 } // end finally
67 } // end method readRecords
68 
69 // use record type to determine if record should be displayed
70 private boolean shouldDisplay( double balance )
71 {
72 if ( ( accountType == MenuOption.CREDIT_BALANCE )
73 && ( balance < 0 ) )
74 return true;
75 
76 else if ( ( accountType == MenuOption.DEBIT_BALANCE )
77 && ( balance > 0 ) )
78 return true;
79 
80 else if ( ( accountType == MenuOption.ZERO_BALANCE )
81 && ( balance == 0 ) )
82 return true;
83 
84 return false;
85 } // end method shouldDisplay
86 
87 // obtain request from user
88 private MenuOption getRequest()
89 {
90 Scanner textIn = new Scanner( System.in );
91 int request = 1 ;
92 
93 // display request options
94 System.out.printf( "
%s
%s
%s
%s
%s
",
95 "Enter request", " 1 - List accounts with zero balances",
96 " 2 - List accounts with credit balances",
97 " 3 - List accounts with debit balances", " 4 - End of run" );
98 
99 try // attempt to input menu choice
100 {
101 do // input user request
102 {
103 System.out.print( "
? " );
104 request = textIn.nextInt();
105 } while ( ( request < 1 ) || ( request > 4 ) );
106 } // end try
107 catch ( NoSuchElementException elementException )
108 {
109 System.err.println( "Invalid input." );
110 System.exit( 1 );
111 } // end catch
112 
113 return choices[ request - 1 ]; // return enum value for option
114 } // end method getRequest
115 
116 public void processRequests()
117 {
118 // get user's request (e.g., zero, credit or debit balance)
119 accountType = getRequest();
120 
121 while ( accountType != MenuOption.END )
122 {
123 switch ( accountType )
124 {
125 case ZERO_BALANCE:
126 System.out.println( "
Accounts with zero balances:
" );
127 break;
128 case CREDIT_BALANCE:
129 System.out.println( "
Accounts with credit balances:
" );
130 break ;
131 case DEBIT_BALANCE:
132 System.out.println( "
Accounts with debit balances:
" );
133 break;
134 } // end switch
135 
136 readRecords();
137 accountType = getRequest();
138 } // end while
139 } // end method processRequests
140 } // end class CreditInquiry

Figure 14.15. Testing the CreditInquiry class.

(This item is displayed on page 696 in the print version)

 1 // Fig. 14.15: CreditInquiryTest.java
 2 // This program tests class CreditInquiry.
 3
 4 public class CreditInquiryTest
 5 {
 6 public static void main( String args[] )
 7 {
 8 CreditInquiry application = new CreditInquiry();
 9 application.processRequests();
10 } // end main
11 } // end class CreditInquiryTest

We begin by creating an enum type (Fig. 14.13) to define the different menu options the user will have. The options and their values are listed in lines 710. Method getValue (lines 1922) retrieves the value of a specific enum constant.

Figure 14.14 contains the functionality for the credit-inquiry program, and Fig. 14.15 contains the main method that executes the program. The program displays a text menu and allows the credit manager to enter one of three options to obtain credit information. Option 1 (ZERO_BALANCE) produces a list of accounts with zero balances. Option 2 (CREDIT_BALANCE) produces a list of accounts with credit balances. Option 3 (DEBIT_BALANCE) produces a list of accounts with debit balances. Option 4 (END) terminates program execution. A sample output is shown in Fig. 14.16.

Figure 14.16. Sample output of the credit-inquiry program in Fig. 14.15.

(This item is displayed on page 696 in the print version)

Enter request
 1 - List accounts with zero balances
 2 - List accounts with credit balances
 3 - List accounts with debit balances
 4 - End of run

? 1

Accounts with zero balances:

300 Pam White 0.00

Enter request
 1 - List accounts with zero balances
 2 - List accounts with credit balances
 3 - List accounts with debit balances
 4 - End of run

? 2

Accounts with credit balances:
200 Steve Doe -345.67
400 Sam Stone -42.16

Enter request
 1 - List accounts with zero balances
 2 - List accounts with credit balances
 3 - List accounts with debit balances
 4 - End of run

? 3

Accounts with debit balances:
100 Bob Jones 24.98
500 Sue Rich 224.62
? 4
 

The record information is collected by reading through the entire file and determining whether each record satisfies the criteria for the account type selected by the credit manager. Method processRequests (lines 116139 of Fig. 14.14) calls method getrequest to display the menu options (line 119) and stores the result in MenuOption variable accountType. Note that getrequest TRanslates the number typed by the user into a MenuOption by using the number to select a MenuOption from array choices. Lines 121138 loop until the user specifies that the program should terminate. The switch statement in lines 123134 displays a header for the current set of records to be output to the screen. Line 136 calls method readRecords (lines 2267), which loops through the file and reads every record.

Line 30 of method readRecords opens the file for reading with a Scanner. Note that the file will be opened for reading with a new Scanner object each time this method is called, so that we can again read from the beginning of the file. Lines 3437 read a record. Line 40 calls method shouldDisplay (lines 7085) to determine whether the current record satisfies the account type requested. If shouldDisplay returns TRue, the program displays the account information. When the end-of-file marker is reached, the loop terminates and line 65 calls the Scanner's close method to close the Scanner and the file. Notice that this occurs in a finally block, which will execute whether or not the file was successfully read. Once all the records have been read, control returns to method processRequests and geTRequest is again called (line 137) to retrieve the user's next menu option. Figure 14.15 contains method main, and calls method processRequests in line 9.

14.5.4. Updating Sequential-Access Files

The data in many sequential files cannot be modified without the risk of destroying other data in the file. For example, if the name "White" needed to be changed to "Worthington," the old name cannot simply be overwritten because the new name requires more space. The record for White was written to the file as

 300 Pam White 0.00

If the record is rewritten beginning at the same location in the file using the new name, the record would be

 300 Pam Worthington 0.00

The new record is larger (has more characters) than the original record. The characters beyond the second "o" in "Worthington" would overwrite the beginning of the next sequential record in the file. The problem here is that fields in a text fileand hence recordscan vary in size. For example, 7, 14,117, 2074 and 27383 are all ints stored in the same number of bytes (4) internally, but they are different-sized fields when displayed on the screen or written to a file as text.

Therefore, records in a sequential-access file are not usually updated in place. Instead, the entire file is usually rewritten. To make the preceding name change, the records before 300 Pam White 0.00 in a sequential-access file would be copied to a new file, the new record (which can be of a different size than the one it replaces) would be written and the records after 300 Pam White 0.00 would be copied to the new file. It is uneconomical just to update one record, but reasonable if a substantial portion of the records needs to be updated.

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net