Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 17 – Files and Streams

Similar presentations


Presentation on theme: "Chapter 17 – Files and Streams"— Presentation transcript:

1 Chapter 17 – Files and Streams
Outline Introduction Data Hierarchy Files and Streams Class File Creating a Sequential-Access File Reading Data from a Sequential-Access File Updating Sequential-Access Files Random-Access Files Creating a Random-Access File Writing Data Randomly to a Random-Access File Reading Data Sequentially from a Random-Access File Case Study: A Transaction-Processing Program New I/O APIs for the Java Platform

2 17.1 Introduction Files Long-term storage of large amounts of data
Persistent data exists after termination of program Files stored on secondary storage devices Magnetic disks Optical disks Magnetic tapes Sequential and random access files

3 Smallest data item in a computer is a bit
17.2 Data Hierarchy Smallest data item in a computer is a bit Bit can be either 0 or 1 Bit short for “binary digit” Programmers work with higher level data items Decimal digits: (0-9) Letters: (A-Z and a-z) Special symbols: (e.g., %, &, *, (, ), -, +, “, :, ?, /, etc.) Java uses Unicode characters composed of 2 bytes A byte is 8 bits long Fields (Java instance variables) Composed of characters or bytes Conveys meaning

4 File is a group of related records
17.2 Data Hierarchy Data hierarchy Data items in a computer form a hierarchy Progresses from bits, to characters, to fields, etc. Records Composed of several fields Implemented as a class in Java See Fig for example File is a group of related records One field in each record is a record key Record key is a unique identifier for a record Sequential file Records stored in order by record key

5 Fig. 17.1 Data hierarchy Randy Red 1 01001010 J u d y Judy Green Sally
Black Tom Blue Iris Orange File Record Field Byte (ASCII character J) Bit

6 Java views a file as a stream of bytes (Fig. 17.2)
17.3 Files and Streams Java views a file as a stream of bytes (Fig. 17.2) File ends with end-of-file marker or a specific byte number File as a stream of bytes associated with an object Java also associates streams with devices System.in, System.out, and System.err Streams can be redirected File processing with classes in package java.io FileInputStream for byte-based input from a file FileOutputStream for byte-based output to a file FileReader for character-based input from a file FileWriter for character-based output to a file

7 Fig. 17.2 Java’s view of a file of n bytes
3 ... 1 2 4 5 8 9 n-1 end-of-file marker 6 7

8 17.3 Files and Streams Buffering Improves performance of I/O
Copies each output to a region of memory called a buffer Entire buffer output to disk at once One long disk access takes less time than many smaller ones BufferedOutputStream buffers file output BufferedInputStream buffers file input

9 Fig. 17.3 lists some useful File methods
17.4 Class File Class File Provides useful information about a file or directory Does not open files or process files Fig lists some useful File methods

10 Fig File methods

11 FileTest.java Line 5 Import java.io package
// Fig. 17.4: FileTest.java // Demonstrating the File class. import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; 7 public class FileTest extends JFrame implements ActionListener { 10 private JTextField enterField; private JTextArea outputArea; 13 // set up GUI public FileTest() { super( "Testing class File" ); 18 enterField = new JTextField( "Enter file or directory name here" ); enterField.addActionListener( this ); outputArea = new JTextArea(); 22 ScrollPane scrollPane = new ScrollPane(); scrollPane.add( outputArea ); 25 FileTest.java Line 5 Import java.io package

12 FileTest.java Line 38 Line 41
Container container = getContentPane(); container.add( enterField, BorderLayout.NORTH ); container.add( scrollPane, BorderLayout.CENTER ); 29 setSize( 400, 400 ); setVisible( true ); 32 } // end constructor 34 // display information about file user specifies public void actionPerformed( ActionEvent actionEvent ) { File name = new File( actionEvent.getActionCommand() ); 39 // if name exists, output information about it if ( name.exists() ) { outputArea.setText( name.getName() + " exists\n" + ( name.isFile() ? "is a file\n" : "is not a file\n" ) + ( name.isDirectory() ? "is a directory\n" : "is not a directory\n" ) + ( name.isAbsolute() ? "is absolute path\n" : "is not absolute path\n" ) + "Last modified: " + name.lastModified() + "\nLength: " + name.length() + "\nPath: " + name.getPath() + "\nAbsolute path: " + name.getAbsolutePath() + "\nParent: " + name.getParent() ); 51 FileTest.java Line 38 Line 41 create a new File and assign it to name Body of if outputs information about the file if it exists

13 FileTest.java Line 53 Lines 57-58 Lines 63-64
// output information if name is a file if ( name.isFile() ) { 54 // append contents of file to outputArea try { BufferedReader input = new BufferedReader( new FileReader( name ) ); StringBuffer buffer = new StringBuffer(); String text; outputArea.append( "\n\n" ); 62 while ( ( text = input.readLine() ) != null ) buffer.append( text + "\n" ); 65 outputArea.append( buffer.toString() ); } 68 // process file processing problems catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "FILE ERROR", "FILE ERROR", JOptionPane.ERROR_MESSAGE ); } 74 } // end if 76 Test if our object is a file FileTest.java Line 53 Lines Lines 63-64 Create reader to gather data from the file Read text until there is no more in the file

14 FileTest.java Line 79 Lines 91-93
// output directory listing else if ( name.isDirectory() ) { String directory[] = name.list(); 80 outputArea.append( "\n\nDirectory contents:\n"); 82 for ( int i = 0; i < directory.length; i++ ) outputArea.append( directory[ i ] + "\n" ); } 86 } // end outer if 88 // not file or directory, output error message else { JOptionPane.showMessageDialog( this, actionEvent.getActionCommand() + " Does Not Exist", "ERROR", JOptionPane.ERROR_MESSAGE ); } 95 } // end method actionPerformed 97 public static void main( String args[] ) { FileTest application = new FileTest(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } 103 104 } // end class FileTest Get a list of the files in the directory FileTest.java Line 79 Lines 91-93 If file does not exist, display error

15 FileTest.java

16 17.5 Creating a Sequential-Access File
Java Files Java imposes no structure on a file Programmer structures file according to application Following program uses simple record structure

17 BankUI.java Line 3 Line 8 Line 17
// Fig. 17.5: BankUI.java // A reusable GUI for the examples in this chapter. package com.deitel.jhtp5.ch17; 4 import java.awt.*; import javax.swing.*; 7 public class BankUI extends JPanel { 9 // label text for GUI protected final static String names[] = { "Account number", "First name", "Last name", "Balance", "Transaction Amount" }; 13 // GUI components; protected for future subclass access protected JLabel labels[]; protected JTextField fields[]; protected JButton doTask1, doTask2; protected JPanel innerPanelCenter, innerPanelSouth; 19 protected int size; // number of text fields in GUI 21 // constants representing text fields in GUI public static final int ACCOUNT = 0, FIRSTNAME = 1, LASTNAME = 2, BALANCE = 3, TRANSACTION = 4; 25 Compile this class in a package for reuse BankUI.java Line 3 Line 8 Line 17 Bank GUI for all examples in this chapter These buttons will perform actions in later examples

18 26 // Set up GUI. Constructor argument size determines the number of
// rows of GUI components. public BankUI( int mySize ) { size = mySize; labels = new JLabel[ size ]; fields = new JTextField[ size ]; 33 // create labels for ( int count = 0; count < labels.length; count++ ) labels[ count ] = new JLabel( names[ count ] ); 37 // create text fields for ( int count = 0; count < fields.length; count++ ) fields[ count ] = new JTextField(); 41 // create panel to lay out labels and fields innerPanelCenter = new JPanel(); innerPanelCenter.setLayout( new GridLayout( size, 2 ) ); 45 // attach labels and fields to innerPanelCenter for ( int count = 0; count < size; count++ ) { innerPanelCenter.add( labels[ count ] ); innerPanelCenter.add( fields[ count ] ); } 51 BankUI.java

19 Return the task buttons
// create generic buttons; no labels or event handlers doTask1 = new JButton(); doTask2 = new JButton(); 55 // create panel to lay out buttons and attach buttons innerPanelSouth = new JPanel(); innerPanelSouth.add( doTask1 ); innerPanelSouth.add( doTask2 ); 60 // set layout of this container and attach panels to it setLayout( new BorderLayout() ); add( innerPanelCenter, BorderLayout.CENTER ); add( innerPanelSouth, BorderLayout.SOUTH ); 65 validate(); // validate layout 67 } // end constructor 69 // return reference to generic task button doTask1 public JButton getDoTask1Button() { return doTask1; } 75 // return reference to generic task button doTask2 public JButton getDoTask2Button() { return doTask2; } BankUI.java Lines 73 and 79 Return the task buttons

20 BankUI.java 81 82 // return reference to fields array of JTextFields
public JTextField[] getFields() { return fields; } 87 // clear content of text fields public void clearFields() { for ( int count = 0; count < size; count++ ) fields[ count ].setText( "" ); } 94 // set text field values; throw IllegalArgumentException if // incorrect number of Strings in argument public void setFieldValues( String strings[] ) throws IllegalArgumentException { if ( strings.length != size ) throw new IllegalArgumentException( "There must be " + size + " Strings in the array" ); 103 for ( int count = 0; count < size; count++ ) fields[ count ].setText( strings[ count ] ); } BankUI.java

21 107 // get array of Strings with current text field contents public String[] getFieldValues() { String values[] = new String[ size ]; 112 for ( int count = 0; count < size; count++ ) values[ count ] = fields[ count ].getText(); 115 return values; } 118 119 } // end class BankUI BankUI.java

22 AccountRecord.java Line 3 Line 7
// Fig. 17.6: AccountRecord.java // A class that represents one record of information. package com.deitel.jhtp5.ch17; 4 import java.io.Serializable; 6 public class AccountRecord implements Serializable { private int account; private String firstName; private String lastName; private double balance; 12 // no-argument constructor calls other constructor with default values public AccountRecord() { this( 0, "", "", 0.0 ); } 18 // initialize a record public AccountRecord( int acct, String first, String last, double bal ) { setAccount( acct ); setFirstName( first ); setLastName( last ); setBalance( bal ); } 27 Compile this class in a package for reuse AccountRecord.java Line 3 Line 7 Implements Serializable so AccountRecords can be used with input and output streams

23 AccountRecord.java 28 // set account number
public void setAccount( int acct ) { account = acct; } 33 // get account number public int getAccount() { return account; } 39 // set first name public void setFirstName( String first ) { firstName = first; } 45 // get first name public String getFirstName() { return firstName; } 51 AccountRecord.java

24 AccountRecord.java 52 // set last name
public void setLastName( String last ) { lastName = last; } 57 // get last name public String getLastName() { return lastName; } 63 // set balance public void setBalance( double bal ) { balance = bal; } 69 // get balance public double getBalance() { return balance; } 75 76 } // end class AccountRecord AccountRecord.java

25 CreateSequentialFile.java Lines 8-9 Lines 22 and 26
// Fig. 17.7: CreateSequentialFile.java // Writing objects sequentially to a file with class ObjectOutputStream. import java.io.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; 7 import com.deitel.jhtp5.ch17.BankUI; import com.deitel.jhtp5.ch17.AccountRecord; 10 11 public class CreateSequentialFile extends JFrame { private ObjectOutputStream output; private BankUI userInterface; private JButton enterButton, openButton; 15 // set up GUI public CreateSequentialFile() { super( "Creating a Sequential File of Objects" ); 20 // create instance of reusable user interface userInterface = new BankUI( 4 ); // four textfields getContentPane().add( userInterface, BorderLayout.CENTER ); 24 // configure button doTask1 for use in this program openButton = userInterface.getDoTask1Button(); openButton.setText( "Save into File ..." ); CreateSequentialFile.java Lines 8-9 Lines 22 and 26 Import our GUI class and record class Create our interface and get a reference to the first task button

26 CreateSequentialFile.java Line 46
28 // register listener to call openFile when button pressed openButton.addActionListener( 31 // anonymous inner class to handle openButton event new ActionListener() { 34 // call openFile when button pressed public void actionPerformed( ActionEvent event ) { openFile(); } 40 } // end anonymous inner class 42 ); // end call to addActionListener 44 // configure button doTask2 for use in this program enterButton = userInterface.getDoTask2Button(); enterButton.setText( "Enter" ); enterButton.setEnabled( false ); // disable button 49 // register listener to call addRecord when button pressed enterButton.addActionListener( 52 CreateSequentialFile.java Line 46 Get a reference to the second task button

27 53 // anonymous inner class to handle enterButton event
new ActionListener() { 55 // call addRecord when button pressed public void actionPerformed( ActionEvent event ) { addRecord(); } 61 } // end anonymous inner class 63 ); // end call to addActionListener 65 // register window listener to handle window closing event addWindowListener( 68 // anonymous inner class to handle windowClosing event new WindowAdapter() { 71 // add current record in GUI to file, then close file public void windowClosing( WindowEvent event ) { if ( output != null ) addRecord(); 77 closeFile(); } CreateSequentialFile.java

28 Instantiate a JFileChooser and assign it to fileChooser
80 } // end anonymous inner class 82 ); // end call to addWindowListener 84 setSize( 300, 200 ); setVisible( true ); 87 } // end CreateSequentialFile constructor 89 // allow user to specify file name private void openFile() { // display file dialog, so user can choose file to open JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 96 int result = fileChooser.showSaveDialog( this ); 98 // if user clicked Cancel button on dialog, return if ( result == JFileChooser.CANCEL_OPTION ) return; 102 File fileName = fileChooser.getSelectedFile(); // get selected file 104 CreateSequentialFile.java Line 94 Line 95 Line 97 Lines Line 103 Instantiate a JFileChooser and assign it to fileChooser Constant FILES_ONLY indicates only files can be selected Method showSaveDialog causes the JFileChooser titled Save to appear Return if user clicked Cancel button on dialog Retrieve selected file

29 CreateSequentialFile.java Open selected file
// display error if invalid if ( fileName == null || fileName.getName().equals( "" ) ) JOptionPane.showMessageDialog( this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 109 else { 111 // open file try { output = new ObjectOutputStream( new FileOutputStream( fileName ) ); 116 openButton.setEnabled( false ); enterButton.setEnabled( true ); } 120 // process exceptions from opening file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error Opening File", "Error", JOptionPane.ERROR_MESSAGE ); } 126 } // end else 128 } // end method openFile 130 CreateSequentialFile.java Open selected file

30 CreateSequentialFile.java Line 132 Line 154
// close file and terminate application private void closeFile() { // close file try { output.close(); System.exit( 0 ); } 139 // process exceptions from closing file catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); System.exit( 1 ); } 146 } // end method closeFile 148 // add record to file public void addRecord() { int accountNumber = 0; AccountRecord record; String fieldValues[] = userInterface.getFieldValues(); 155 Method closeFile closes the current file CreateSequentialFile.java Line 132 Line 154 Get the data in the textfields

31 CreateSequentialFile.java Lines 167-170 Lines 173-174
// if account field value is not empty if ( ! fieldValues[ BankUI.ACCOUNT ].equals( "" ) ) { 158 // output values to file try { accountNumber = Integer.parseInt( fieldValues[ BankUI.ACCOUNT ] ); 163 if ( accountNumber > 0 ) { 165 // create new record record = new AccountRecord( accountNumber, fieldValues[ BankUI.FIRSTNAME ], fieldValues[ BankUI.LASTNAME ], Double.parseDouble( fieldValues[ BankUI.BALANCE ] ) ); 171 // output record and flush buffer output.writeObject( record ); output.flush(); } 176 else { JOptionPane.showMessageDialog( this, "Account number must be greater than 0", "Bad account number", JOptionPane.ERROR_MESSAGE ); } 182 CreateSequentialFile.java Lines Lines Create a new record Write the record to the file immediately

32 CreateSequentialFile.java 183 // clear textfields
userInterface.clearFields(); 185 } // end try 187 // process invalid account number or balance format catch ( NumberFormatException formatException ) { JOptionPane.showMessageDialog( this, "Bad account number or balance", "Invalid Number Format", JOptionPane.ERROR_MESSAGE ); } 194 // process exceptions from file output catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error writing to file", "IO Exception", JOptionPane.ERROR_MESSAGE ); closeFile(); } 201 } // end if 203 } // end method addRecord 205 CreateSequentialFile.java

33 CreateSequentialFile.java 206 public static void main( String args[] )
{ new CreateSequentialFile(); } 210 211 } // end class CreateSequentialFile CreateSequentialFile.java BankUI graphical user interface

34 CreateSequentialFile.java Select location for file here
Files and directories are displayed here Click Save to submit new file name to program

35 17.6 Reading Data from a Sequential-Access File
Data stored in files Retrieved for processing when needed Accessing a sequential file Data must be read in same format it was written

36 Fig. 17.8 Sample data for the program of Fig. 17.7

37 ReadSequentialFile.java Line 22
// Fig. 17.9: ReadSequentialFile.java // This program reads a file of objects sequentially // and displays each record. import java.io.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; 8 import com.deitel.jhtp5.ch17.*; 10 11 public class ReadSequentialFile extends JFrame { private ObjectInputStream input; private BankUI userInterface; private JButton nextButton, openButton; 15 // Constructor -- initialize the Frame public ReadSequentialFile() { super( "Reading a Sequential File of Objects" ); 20 // create instance of reusable user interface userInterface = new BankUI( 4 ); // four textfields getContentPane().add( userInterface, BorderLayout.CENTER ); 24 ReadSequentialFile.java Line 22 Create user interface

38 ReadSequentialFile.java Line 27
// get reference to generic task button doTask1 from BankUI openButton = userInterface.getDoTask1Button(); openButton.setText( "Open File" ); 28 // register listener to call openFile when button pressed openButton.addActionListener( 31 // anonymous inner class to handle openButton event new ActionListener() { 34 // close file and terminate application public void actionPerformed( ActionEvent event ) { openFile(); } 40 } // end anonymous inner class 42 ); // end call to addActionListener 44 // register window listener for window closing event addWindowListener( 47 // anonymous inner class to handle windowClosing event new WindowAdapter() { 50 Get a reference to the first task button ReadSequentialFile.java Line 27

39 ReadSequentialFile.java Line 65
// close file and terminate application public void windowClosing( WindowEvent event ) { if ( input != null ) closeFile(); 56 System.exit( 0 ); } 59 } // end anonymous inner class 61 ); // end call to addWindowListener 63 // get reference to generic task button doTask2 from BankUI nextButton = userInterface.getDoTask2Button(); nextButton.setText( "Next Record" ); nextButton.setEnabled( false ); 68 // register listener to call readRecord when button pressed nextButton.addActionListener( 71 // anonymous inner class to handle nextRecord event new ActionListener() { 74 ReadSequentialFile.java Line 65 Get a reference to the second task button

40 ReadSequentialFile.java Line 95 Line 96 Line 98
// call readRecord when user clicks nextRecord public void actionPerformed( ActionEvent event ) { readRecord(); } 80 } // end anonymous inner class 82 ); // end call to addActionListener 84 pack(); setSize( 300, 200 ); setVisible( true ); 88 } // end ReadSequentialFile constructor 90 // enable user to select file to open private void openFile() { // display file dialog so user can select file to open JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 97 int result = fileChooser.showOpenDialog( this ); 99 ReadSequentialFile.java Line 95 Line 96 Line 98 Instantiate a JFileChooser and assign it to fileChooser Constant FILES_ONLY indicates only files can be selected Method showOpenDialog causes the JFileChooser titled Open to appear

41 ReadSequentialFile.java Line 101-102 Line 105 Lines 116-117
// if user clicked Cancel button on dialog, return if ( result == JFileChooser.CANCEL_OPTION ) return; 103 // obtain selected file File fileName = fileChooser.getSelectedFile(); 106 // display error if file name invalid if ( fileName == null || fileName.getName().equals( "" ) ) JOptionPane.showMessageDialog( this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 111 else { 113 // open file try { input = new ObjectInputStream( new FileInputStream( fileName ) ); 118 openButton.setEnabled( false ); nextButton.setEnabled( true ); } 122 // process exceptions opening file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error Opening File", "Error", JOptionPane.ERROR_MESSAGE ); } Return if user clicked Cancel button on dialog ReadSequentialFile.java Line Line 105 Lines Retrieve selected file Open selected file

42 ReadSequentialFile.java Line 140
128 } // end else 130 } // end method openFile 132 // read record from file public void readRecord() { AccountRecord record; 137 // input the values from the file try { record = ( AccountRecord ) input.readObject(); 141 // create array of Strings to display in GUI String values[] = { String.valueOf( record.getAccount() ), record.getFirstName(), record.getLastName(), String.valueOf( record.getBalance() ) }; 146 // display record contents userInterface.setFieldValues( values ); } 150 // display message when end-of-file reached catch ( EOFException endOfFileException ) { nextButton.setEnabled( false ); 154 ReadSequentialFile.java Line 140 Method readObject reads an Object from the ObjectInputStream

43 ReadSequentialFile.java Line 175
JOptionPane.showMessageDialog( this, "No more records in file", "End of File", JOptionPane.ERROR_MESSAGE ); } 158 // display error message if class is not found catch ( ClassNotFoundException classNotFoundException ) { JOptionPane.showMessageDialog( this, "Unable to create object", "Class Not Found", JOptionPane.ERROR_MESSAGE ); } 164 // display error message if cannot read due to problem with file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error during read from file", "Read Error", JOptionPane.ERROR_MESSAGE ); } 171 } // end method readRecord 173 // close file and terminate application private void closeFile() { // close file and exit try { input.close(); System.exit( 0 ); } ReadSequentialFile.java Line 175 Method closeFile closes the current file

44 ReadSequentialFile.java 182
// process exception while closing file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); 187 System.exit( 1 ); } 190 } // end method closeFile 192 public static void main( String args[] ) { new ReadSequentialFile(); } 197 198 } // end class ReadSequentialFile ReadSequentialFile.java

45 ReadSequentialFile.java

46 CreditInquiry.java 1 // Fig. 17.10: CreditInquiry.java
// This program reads a file sequentially and displays the contents in a // text area based on the type of account the user requests // (credit balance, debit balance or zero balance). import java.io.*; import java.awt.*; import java.awt.event.*; import java.text.DecimalFormat; import javax.swing.*; 10 11 import com.deitel.jhtp5.ch17.AccountRecord; 12 13 public class CreditInquiry extends JFrame { private JTextArea recordDisplayArea; private JButton openButton, creditButton, debitButton, zeroButton; private JPanel buttonPanel; 17 private ObjectInputStream input; private FileInputStream fileInput; private File fileName; private String accountType; 22 static private DecimalFormat twoDigits = new DecimalFormat( "0.00" ); 24 // set up GUI public CreditInquiry() { CreditInquiry.java

47 CreditInquiry.java 28 super( "Credit Inquiry Program" ); 29
Container container = getContentPane(); 31 buttonPanel = new JPanel(); // set up panel for buttons 33 // create and configure button to open file openButton = new JButton( "Open File" ); buttonPanel.add( openButton ); 37 // register openButton listener openButton.addActionListener( 40 // anonymous inner class to handle openButton event new ActionListener() { 43 // open file for processing public void actionPerformed( ActionEvent event ) { openFile(); } 49 } // end anonymous inner class 51 ); // end call to addActionListener CreditInquiry.java

48 53 // create and configure button to get accounts with credit balances creditButton = new JButton( "Credit balances" ); buttonPanel.add( creditButton ); creditButton.addActionListener( new ButtonHandler() ); 58 // create and configure button to get accounts with debit balances debitButton = new JButton( "Debit balances" ); buttonPanel.add( debitButton ); debitButton.addActionListener( new ButtonHandler() ); 63 // create and configure button to get accounts with zero balances zeroButton = new JButton( "Zero balances" ); buttonPanel.add( zeroButton ); zeroButton.addActionListener( new ButtonHandler() ); 68 // set up display area recordDisplayArea = new JTextArea(); JScrollPane scroller = new JScrollPane( recordDisplayArea ); 72 // attach components to content pane container.add( scroller, BorderLayout.CENTER ); container.add( buttonPanel, BorderLayout.SOUTH ); 76 CreditInquiry.java

49 77 creditButton.setEnabled( false ); // disable creditButton
debitButton.setEnabled( false ); // disable debitButton zeroButton.setEnabled( false ); // disable zeroButton 80 // register window listener addWindowListener( 83 // anonymous inner class for windowClosing event new WindowAdapter() { 86 // close file and terminate program public void windowClosing( WindowEvent event ) { closeFile(); System.exit( 0 ); } 93 } // end anonymous inner class 95 ); // end call to addWindowListener 97 pack(); // pack components and display window setSize( 600, 250 ); setVisible( true ); 101 } // end CreditInquiry constructor 103 CreditInquiry.java

50 CreditInquiry.java 104 // enable user to choose file to open
private void openFile() { // display dialog, so user can choose file JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 110 int result = fileChooser.showOpenDialog( this ); 112 // if user clicked Cancel button on dialog, return if ( result == JFileChooser.CANCEL_OPTION ) return; 116 fileName = fileChooser.getSelectedFile(); // obtain selected file 118 // display error if file name invalid if ( fileName == null || fileName.getName().equals( "" ) ) JOptionPane.showMessageDialog( this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 123 // open file try { 126 // close file from previous operation if ( input != null ) input.close(); 130 CreditInquiry.java

51 CreditInquiry.java 131 fileInput = new FileInputStream( fileName );
input = new ObjectInputStream( fileInput ); openButton.setEnabled( false ); creditButton.setEnabled( true ); debitButton.setEnabled( true ); zeroButton.setEnabled( true ); } 138 // catch problems manipulating file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "File does not exist", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); } 144 } // end method openFile 146 // close file before application terminates private void closeFile() { // close file try { if ( input != null ) input.close(); } 155 CreditInquiry.java

52 CreditInquiry.java Lines 177-178
// process exception from closing file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); 160 System.exit( 1 ); } 163 } // end method closeFile 165 // read records from file and display only records of appropriate type private void readRecords() { AccountRecord record; 170 // read records try { 173 if ( input != null ) input.close(); 176 fileInput = new FileInputStream( fileName ); input = new ObjectInputStream( fileInput ); 179 recordDisplayArea.setText( "The accounts are:\n" ); 181 CreditInquiry.java Lines Create a stream from which to read the records

53 CreditInquiry.java Line 186 Line 198
// input the values from the file while ( true ) { 184 // read one AccountRecord record = ( AccountRecord ) input.readObject(); 187 // if proper acount type, display record if ( shouldDisplay( record.getBalance() ) ) recordDisplayArea.append( record.getAccount() + "\t" + record.getFirstName() + "\t" + record.getLastName() + "\t" + twoDigits.format( record.getBalance() ) + "\n" ); } 194 } // end try 196 // close file when end-of-file reached catch ( EOFException eofException ) { closeFile(); } 201 // display error if cannot read object because class not found catch ( ClassNotFoundException classNotFound ) { JOptionPane.showMessageDialog( this, "Unable to create object", "Class Not Found", JOptionPane.ERROR_MESSAGE ); } Method readObject reads an Object from the ObjectInputStream CreditInquiry.java Line 186 Line 198 An EOFException is thrown when the end of the file is reached

54 207 // display error if cannot read because problem with file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error reading from file", "Error", JOptionPane.ERROR_MESSAGE ); } 213 } // end method readRecords 215 // use record type to determine if record should be displayed private boolean shouldDisplay( double balance ) { if ( accountType.equals( "Credit balances" ) && balance < 0 ) return true; 221 else if ( accountType.equals( "Debit balances" ) && balance > 0 ) return true; 224 else if ( accountType.equals( "Zero balances" ) && balance == 0 ) return true; 227 return false; } 230 CreditInquiry.java

55 CreditInquiry.java 231 public static void main( String args[] ) 232 {
{ new CreditInquiry(); } 235 // class for creditButton, debitButton and zeroButton event handling private class ButtonHandler implements ActionListener { 238 // read records from file public void actionPerformed( ActionEvent event ) { accountType = event.getActionCommand(); readRecords(); } 245 } // end class ButtonHandler 247 248 } // end class CreditInquiry CreditInquiry.java

56 CreditInquiry.java

57 17.7 Updating Sequential-Access Files
Difficult to update a sequential-access file Entire file must be rewritten to change one field Only acceptable if many records being updated at once

58 “Instant-access” applications
17.8 Random-Access Files “Instant-access” applications Record must be located immediately Transaction-processing systems require rapid access Random-access files Access individual records directly and quickly Use fixed length for every record Easy to calculate record locations Insert records without destroying other data in file Fig shows random-access file

59 Fig. 17.11 Java’s view of a random-access file
100 bytes 200 300 400 500 byte offsets

60 17.9 Creating a Random-Access File
RandomAccessFile objects Like DataInputStream and DataOutputstream Reads or writes data in spot specified by file-position pointer Manipulates all data as primitive types Normally writes one object at a time to file

61 RandomAccessAccountRecord.java Line 7
// Fig : RandomAccessAccountRecord.java // Subclass of AccountRecord for random access file programs. package com.deitel.jhtp5.ch17; 4 import java.io.*; 6 public class RandomAccessAccountRecord extends AccountRecord { 8 public static final int SIZE = 72; // bytes in one record 10 // no-argument constructor calls other constructor with default values public RandomAccessAccountRecord() { this( 0, "", "", 0.0 ); } 16 // initialize a RandomAccessAccountRecord public RandomAccessAccountRecord( int account, String firstName, String lastName, double balance ) { super( account, firstName, lastName, balance ); } 23 Class extends AccountRecord RandomAccessAccountRecord.java Line 7

62 RandomAccessAccountRecord.java Line 25 Line 27 Line 30 Line 39
// read a record from specified RandomAccessFile public void read( RandomAccessFile file ) throws IOException { setAccount( file.readInt() ); setFirstName( readName( file ) ); setLastName( readName( file ) ); setBalance( file.readDouble() ); } 32 // ensure that name is proper length private String readName( RandomAccessFile file ) throws IOException { char name[] = new char[ 15 ], temp; 37 for ( int count = 0; count < name.length; count++ ) { temp = file.readChar(); name[ count ] = temp; } 42 return new String( name ).replace( '\0', ' ' ); } 45 Method read reads one record from the RandomAccessFile RandomAccessAccountRecord.java Line 25 Line 27 Line 30 Line 39 Method readInt reads one integer Method readDouble reads one double Method readChar reads one character

63 RandomAccessAccountRecord.java Line 47 Line 49 Line 52 Line 56 Line 67
// write a record to specified RandomAccessFile public void write( RandomAccessFile file ) throws IOException { file.writeInt( getAccount() ); writeName( file, getFirstName() ); writeName( file, getLastName() ); file.writeDouble( getBalance() ); } 54 // write a name to file; maximum of 15 characters private void writeName( RandomAccessFile file, String name ) throws IOException { StringBuffer buffer = null; 60 if ( name != null ) buffer = new StringBuffer( name ); else buffer = new StringBuffer( 15 ); 65 buffer.setLength( 15 ); file.writeChars( buffer.toString() ); } 69 70 } // end class RandomAccessAccountRecord Method write writes one record to the RandomAccessFile RandomAccessAccountRecord.java Line 47 Line 49 Line 52 Line 56 Line 67 Method writeInt writes one integer Method writeDouble writes one double Method writeName writes a string to the file Method writeChars writes a string

64 CreateRandomFile.java 1 // Fig. 17.13: CreateRandomFile.java
// Creates random access file by writing 100 empty records to disk. import java.io.*; import javax.swing.*; 5 import com.deitel.jhtp5.ch17.RandomAccessAccountRecord; 7 public class CreateRandomFile { 9 private static final int NUMBER_RECORDS = 100; 11 // enable user to select file to open private void createFile() { // display dialog so user can choose file JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 18 int result = fileChooser.showSaveDialog( null ); 20 // if user clicked Cancel button on dialog, return if ( result == JFileChooser.CANCEL_OPTION ) return; 24 // obtain selected file File fileName = fileChooser.getSelectedFile(); CreateRandomFile.java

65 CreateRandomFile.java Lines 37-38 Line 45
27 // display error if file name invalid if ( fileName == null || fileName.getName().equals( "" ) ) JOptionPane.showMessageDialog( null, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 32 else { 34 // open file try { RandomAccessFile file = new RandomAccessFile( fileName, "rw" ); 39 RandomAccessAccountRecord blankRecord = new RandomAccessAccountRecord(); 42 // write 100 blank records for ( int count = 0; count < NUMBER_RECORDS; count++ ) blankRecord.write( file ); 46 file.close(); // close file 48 // display message that file was created JOptionPane.showMessageDialog( null, "Created file " + fileName, "Status", JOptionPane.INFORMATION_MESSAGE ); CreateRandomFile.java Lines Line 45 Open a RandomAccessFile Write 100 blank records

66 CreateRandomFile.java 52 53 System.exit( 0 ); // terminate program 54
} // end try 56 // process exceptions during open, write or close file operations catch ( IOException ioException ) { JOptionPane.showMessageDialog( null, "Error processing file", "Error processing file", JOptionPane.ERROR_MESSAGE ); 61 System.exit( 1 ); } 64 } // end else 66 } // end method createFile 68 public static void main( String args[] ) { CreateRandomFile application = new CreateRandomFile(); application.createFile(); } 74 75 } // end class CreateRandomFile CreateRandomFile.java

67 CreateRandomFile.java

68 17.10 Writing Data Randomly to a Random-Access File
RandomAccessFile method seek Determines location in file where record is stored Sets file-position pointer to a specific point in file

69 WriteRandomFile.java 1 // Fig. 17.14: WriteRandomFile.java
// This program uses textfields to get information from the user at the // keyboard and writes the information to a random-access file. import java.awt.*; import java.awt.event.*; import java.io.*; import javax.swing.*; 8 import com.deitel.jhtp5.ch17.*; 10 11 public class WriteRandomFile extends JFrame { private RandomAccessFile output; private BankUI userInterface; private JButton enterButton, openButton; 15 private static final int NUMBER_RECORDS = 100; 17 // set up GUI public WriteRandomFile() { super( "Write to random access file" ); 22 // create instance of reusable user interface BankUI userInterface = new BankUI( 4 ); // four textfields getContentPane().add( userInterface, BorderLayout.CENTER ); WriteRandomFile.java

70 27 // get reference to generic task button doTask1 in BankUI openButton = userInterface.getDoTask1Button(); openButton.setText( "Open..." ); 31 // register listener to call openFile when button pressed openButton.addActionListener( 34 // anonymous inner class to handle openButton event new ActionListener() { 37 // allow user to select file to open public void actionPerformed( ActionEvent event ) { openFile(); } 43 } // end anonymous inner class 45 ); // end call to addActionListener 47 // register window listener for window closing event addWindowListener( 50 WriteRandomFile.java

71 51 // anonymous inner class to handle windowClosing event
new WindowAdapter() { 53 // add record in GUI, then close file public void windowClosing( WindowEvent event ) { if ( output != null ) addRecord(); 59 closeFile(); } 62 } // end anonymous inner class 64 ); // end call to addWindowListener 66 // get reference to generic task button doTask2 in BankUI enterButton = userInterface.getDoTask2Button(); enterButton.setText( "Enter" ); enterButton.setEnabled( false ); 71 // register listener to call addRecord when button pressed enterButton.addActionListener( 74 WriteRandomFile.java

72 75 // anonymous inner class to handle enterButton event
new ActionListener() { 77 // add record to file public void actionPerformed( ActionEvent event ) { addRecord(); } 83 } // end anonymous inner class 85 ); // end call to addActionListener 87 setSize( 300, 150 ); setVisible( true ); } 91 // enable user to choose file to open private void openFile() { // display file dialog so user can select file JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 98 int result = fileChooser.showOpenDialog( this ); 100 WriteRandomFile.java

73 WriteRandomFile.java Line 117
// if user clicked Cancel button on dialog, return if ( result == JFileChooser.CANCEL_OPTION ) return; 104 // obtain selected file File fileName = fileChooser.getSelectedFile(); 107 // display error if file name invalid if ( fileName == null || fileName.getName().equals( "" ) ) JOptionPane.showMessageDialog( this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 112 else { 114 // open file try { output = new RandomAccessFile( fileName, "rw" ); enterButton.setEnabled( true ); openButton.setEnabled( false ); } 121 // process exception while opening file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "File does not exist", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); } WriteRandomFile.java Line 117 Open a RandomAccessFile

74 WriteRandomFile.java 127 128 } // end else 129
} // end method openFile 131 // close file and terminate application private void closeFile() { // close file and exit try { if ( output != null ) output.close(); 139 System.exit( 0 ); } 142 // process exception while closing file catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); 147 System.exit( 1 ); } 150 } // end method closeFile 152 WriteRandomFile.java

75 WriteRandomFile.java Lines 176-177
// add one record to file private void addRecord() { String fields[] = userInterface.getFieldValues(); 157 // ensure account field has a value if ( ! fields[ BankUI.ACCOUNT ].equals( "" ) ) { 160 // output values to file try { int accountNumber = Integer.parseInt( fields[ ACCOUNT ] ); 165 if ( accountNumber > 0 && accountNumber <= NUMBER_RECORDS ) { RandomAccessAccountRecord record new RandomAccessAccountRecord(); 169 record.setAccount( accountNumber ); record.setFirstName( fields[ BankUI.FIRSTNAME ] ); record.setLastName( fields[ BankUI.LASTNAME ] ); record.setBalance( Double.parseDouble( fields[ BankUI.BALANCE ] ) ); 175 output.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE ); record.write( output ); } WriteRandomFile.java Lines Set the file pointer to the appropriate place

76 WriteRandomFile.java 180 181 else {
JOptionPane.showMessageDialog( this, "Account must be between 1 and 100", "Invalid account number", JOptionPane.ERROR_MESSAGE ); } 186 userInterface.clearFields(); // clear TextFields 188 } // end try 190 // process improper account number or balance format catch ( NumberFormatException formatException ) { JOptionPane.showMessageDialog( this, "Bad account number or balance", "Invalid Number Format", JOptionPane.ERROR_MESSAGE ); } 197 // process exceptions while writing to file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error writing to the file", "IO Exception", JOptionPane.ERROR_MESSAGE ); closeFile(); } WriteRandomFile.java

77 WriteRandomFile.java 205 206 } // end if 207
} // end method addRecord 209 public static void main( String args[] ) { new WriteRandomFile(); } 214 215 } // end class WriteRandomFile WriteRandomFile.java

78 WriteRandomFile.java

79 17.11 Reading Data Sequentially from a Random-Access File
Read all valid records in a RandomAccessFile

80 ReadRandomFile.java 1 // Fig. 17.15: ReadRandomFile.java
// This program reads a random-access file sequentially and // displays the contents one record at a time in text fields. import java.awt.*; import java.awt.event.*; import java.io.*; import java.text.DecimalFormat; import javax.swing.*; 9 10 import com.deitel.jhtp5.ch17.*; 11 12 public class ReadRandomFile extends JFrame { private BankUI userInterface; private RandomAccessFile input; private JButton nextButton, openButton; 16 private static DecimalFormat twoDigits = new DecimalFormat( "0.00" ); 18 // set up GUI public ReadRandomFile() { super( "Read Client File" ); 23 // create reusable user interface instance userInterface = new BankUI( 4 ); // four textfields getContentPane().add( userInterface ); ReadRandomFile.java

81 27 // configure generic doTask1 button from BankUI openButton = userInterface.getDoTask1Button(); openButton.setText( "Open File for Reading..." ); 31 // register listener to call openFile when button pressed openButton.addActionListener( 34 // anonymous inner class to handle openButton event new ActionListener() { 37 // enable user to select file to open public void actionPerformed( ActionEvent event ) { openFile(); } 43 } // end anonymous inner class 45 ); // end call to addActionListener 47 // configure generic doTask2 button from BankUI nextButton = userInterface.getDoTask2Button(); nextButton.setText( "Next" ); nextButton.setEnabled( false ); ReadRandomFile.java

82 52 // register listener to call readRecord when button pressed nextButton.addActionListener( 55 // anonymous inner class to handle nextButton event new ActionListener() { 58 // read a record when user clicks nextButton public void actionPerformed( ActionEvent event ) { readRecord(); } 64 } // end anonymous inner class 66 ); // end call to addActionListener 68 // register listener for window closing event addWindowListener( 71 // anonymous inner class to handle windowClosing event new WindowAdapter() { 74 ReadRandomFile.java

83 ReadRandomFile.java 75 // close file and terminate application
public void windowClosing( WindowEvent event ) { closeFile(); } 80 } // end anonymous inner class 82 ); // end call to addWindowListener 84 setSize( 300, 150 ); setVisible( true ); 87 } // end constructor 89 // enable user to select file to open private void openFile() { // display file dialog so user can select file JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 96 int result = fileChooser.showOpenDialog( this ); 98 ReadRandomFile.java

84 ReadRandomFile.java Line 115
// if user clicked Cancel button on dialog, return if ( result == JFileChooser.CANCEL_OPTION ) return; 102 // obtain selected file File fileName = fileChooser.getSelectedFile(); 105 // display error is file name invalid if ( fileName == null || fileName.getName().equals( "" ) ) JOptionPane.showMessageDialog( this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); 110 else { 112 // open file try { input = new RandomAccessFile( fileName, "r" ); nextButton.setEnabled( true ); openButton.setEnabled( false ); } 119 // catch exception while opening file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "File does not exist", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); } ReadRandomFile.java Line 115 Open a RandomAccessFile

85 ReadRandomFile.java Line 139
125 } // end else 127 } // end method openFile 129 // read one record private void readRecord() { RandomAccessAccountRecord record = new RandomAccessAccountRecord(); 134 // read a record and display try { 137 do { record.read( input ); } while ( record.getAccount() == 0 ); 141 String values[] = { String.valueOf( record.getAccount() ), record.getFirstName(), record.getLastName(), String.valueOf( record.getBalance() ) }; userInterface.setFieldValues( values ); } 147 ReadRandomFile.java Line 139 Read until a valid record is found

86 ReadRandomFile.java Line 149
// close file when end-of-file reached catch ( EOFException eofException ) { JOptionPane.showMessageDialog( this, "No more records", "End-of-file reached", JOptionPane.INFORMATION_MESSAGE ); closeFile(); } 154 // process exceptions from problem with file catch ( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error Reading File", "Error", JOptionPane.ERROR_MESSAGE ); 159 System.exit( 1 ); } 162 } // end method readRecord 164 // close file and terminate application private void closeFile() { // close file and exit try { if ( input != null ) input.close(); 172 System.exit( 0 ); } If the end-of-file marker is reached, there are no more records ReadRandomFile.java Line 149

87 ReadRandomFile.java 175 176 // process exception closing file
catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); 180 System.exit( 1 ); } 183 } // end method closeFile 185 public static void main( String args[] ) { new ReadRandomFile(); } 190 191 } // end class ReadRandomFile ReadRandomFile.java

88 ReadRandomFile.java

89 17.12 Case Study: A Transaction-Processing Program
Substantial transaction-processing system Uses random-access file Updates, adds and deletes accounts

90 Fig. 17.16 Transaction Processor window

91 Fig. 17.17 Update Record: Loading a record to update
Type account number and press the Enter key to load record. Action button has a different label depending on the operation to perform.

92 Fig. 17.18 Update Record: Inputting a transaction
Updated balance after user pressed Update. Enter transaction amount.

93 Fig. 17.19 New Record: Adding a record to the file

94 Fig. 17.20 Delete Record: Removing a record from the file

95 TransactionProcessor.java 1 // Fig. 17.21: TransactionProcessor.java
// A transaction processing program using random-access files. import java.awt.*; import java.awt.event.*; import java.io.*; import java.text.DecimalFormat; import javax.swing.*; 8 import com.deitel.jhtp5.ch17.*; 10 11 public class TransactionProcessor extends JFrame { 12 private BankUI userInterface; private JMenuItem newItem, updateItem, deleteItem, openItem, exitItem; private JTextField fields[]; private JTextField accountField, transactionField; private JButton actionButton, cancelButton; private FileEditor dataFile; private RandomAccessAccountRecord record; 20 public TransactionProcessor() { super( "Transaction Processor" ); 24 TransactionProcessor.java

96 TransactionProcessor.java 25 // set up desktop, menu bar and File menu
userInterface = new BankUI( 5 ); getContentPane().add( userInterface ); userInterface.setVisible( false ); 29 // set up the action button actionButton = userInterface.getDoTask1Button(); actionButton.setText( "Save Changes" ); actionButton.setEnabled( false ); 34 // register action button listener actionButton.addActionListener( 37 new ActionListener() { // anonymous inner class 39 public void actionPerformed( ActionEvent event ) { String action = event.getActionCommand(); performAction( action ); 44 } // end method actionPerformed 46 } // end anonymous inner class 48 ); // end call to addActionListener 50 TransactionProcessor.java

97 TransactionProcessor.java 51 // set up the cancel button
cancelButton = userInterface.getDoTask2Button(); cancelButton.setText( "Cancel" ); cancelButton.setEnabled( false ); 55 // register cancel button listener cancelButton.addActionListener( 58 new ActionListener() { // anonymous inner class 60 // clear the fields public void actionPerformed( ActionEvent event ) { userInterface.clearFields(); } 66 } // end anonymous inner class 68 ); // end call to addActionListener 70 // set up the listener for the account field fields = userInterface.getFields(); accountField = fields[ BankUI.ACCOUNT ]; accountField.addActionListener( 75 TransactionProcessor.java

98 76 new ActionListener() { // anonymous inner class
77 public void actionPerformed( ActionEvent event ) { displayRecord( "0" ); } 82 } // end anonymous inner class 84 ); // end call to addActionListener 86 // create reference to the transaction field transactionField = fields[ BankUI.TRANSACTION ]; 89 // register transaction field listener transactionField.addActionListener( 92 new ActionListener() { // anonymous inner class 94 // update the GUI fields public void actionPerformed( ActionEvent event ) { displayRecord( transactionField.getText() ); } 100 } // end anonymous inner class 102 TransactionProcessor.java

99 TransactionProcessor.java 103 ); // end call to addActionListener 104
JMenuBar menuBar = new JMenuBar(); // set up the menu setJMenuBar( menuBar ); 107 JMenu fileMenu = new JMenu( "File" ); menuBar.add( fileMenu ); 110 // set up menu item for adding a record newItem = new JMenuItem( "New Record" ); newItem.setEnabled( false ); 114 // register new item listener newItem.addActionListener( 117 new ActionListener() { // anonymous inner class 119 public void actionPerformed( ActionEvent event ) { 122 // set up the GUI fields for editing fields[ BankUI.ACCOUNT ].setEnabled( true ); fields[ BankUI.FIRSTNAME ].setEnabled( true ); fields[ BankUI.LASTNAME ].setEnabled( true ); fields[ BankUI.BALANCE ].setEnabled( true ); fields[ BankUI.TRANSACTION ].setEnabled( false ); TransactionProcessor.java

100 TransactionProcessor.java 129 130 actionButton.setEnabled( true );
actionButton.setText( "Create" ); cancelButton.setEnabled( true ); 133 userInterface.clearFields(); // reset the textfields 135 } // end method actionPerformed 137 } // end anonymous inner class 139 ); // end call to addActionListener 141 // set up menu item for updating a record updateItem = new JMenuItem( "Update Record" ); updateItem.setEnabled( false ); 145 // register update item listener updateItem.addActionListener( 148 new ActionListener() { // anonymous inner class 150 public void actionPerformed( ActionEvent event ) { TransactionProcessor.java

101 TransactionProcessor.java 153 // set up the GUI fields for editing
fields[ BankUI.ACCOUNT ].setEnabled( true ); fields[ BankUI.FIRSTNAME ].setEnabled( false ); fields[ BankUI.LASTNAME ].setEnabled( false ); fields[ BankUI.BALANCE ].setEnabled( false ); fields[ BankUI.TRANSACTION ].setEnabled( true ); 159 actionButton.setEnabled( true ); actionButton.setText( "Update" ); cancelButton.setEnabled( true ); 163 userInterface.clearFields(); // reset the textfields 165 } // end method actionPerformed 167 } // end anonymous inner class 169 ); // end call to addActionListener 171 // set up menu item for deleting a record deleteItem = new JMenuItem( "Delete Record" ); deleteItem.setEnabled( false ); 175 // register delete item listener deleteItem.addActionListener( 178 TransactionProcessor.java

102 179 new ActionListener() { // anonymous inner class
180 public void actionPerformed( ActionEvent event ) { // set up the GUI fields for editing fields[ BankUI.ACCOUNT ].setEnabled( true ); fields[ BankUI.FIRSTNAME ].setEnabled( false ); fields[ BankUI.LASTNAME ].setEnabled( false ); fields[ BankUI.BALANCE ].setEnabled( false ); fields[ BankUI.TRANSACTION ].setEnabled( false ); 189 actionButton.setEnabled( true ); actionButton.setText( "Delete" ); cancelButton.setEnabled( true ); 193 userInterface.clearFields(); // reset the textfields 195 } // end method actionPerformed 197 } // end anonymous inner class 199 ); // end call to addActionListener 201 // set up menu item for opening file openItem = new JMenuItem( "New/Open File" ); 204 TransactionProcessor.java

103 TransactionProcessor.java 205 // register open item listener
openItem.addActionListener( 207 new ActionListener() { // anonymous inner class 209 public void actionPerformed( ActionEvent event ) { // try to open the file if ( !openFile() ) return; 215 // set up the menu items newItem.setEnabled( true ); updateItem.setEnabled( true ); deleteItem.setEnabled( true ); openItem.setEnabled( false ); 221 // set the interface userInterface.setVisible( true ); fields[ BankUI.ACCOUNT ].setEnabled( false ); fields[ BankUI.FIRSTNAME ].setEnabled( false ); fields[ BankUI.LASTNAME ].setEnabled( false ); fields[ BankUI.BALANCE ].setEnabled( false ); fields[ BankUI.TRANSACTION ].setEnabled( false ); 229 } // end method actionPerformed 231 TransactionProcessor.java

104 TransactionProcessor.java 232 } // end anonymous inner class 233
); // end call to addActionListener 235 // set up menu item for exiting program exitItem = new JMenuItem( "Exit" ); 238 // register exit item listener exitItem.addActionListener( 241 new ActionListener() { // anonyomus inner class 243 public void actionPerformed( ActionEvent event ) { try { dataFile.closeFile(); // close the file } 249 catch ( IOException ioException ) { JOptionPane.showMessageDialog( TransactionProcessor.this, "Error closing file", "IO Error", JOptionPane.ERROR_MESSAGE ); } 255 finally { System.exit( 0 ); // exit the program } TransactionProcessor.java

105 TransactionProcessor.java 259 260 } // end method actionPerformed 261
} // end anonymous inner class 263 ); // end call to addActionListener 265 // attach menu items to File menu fileMenu.add( openItem ); fileMenu.add( newItem ); fileMenu.add( updateItem ); fileMenu.add( deleteItem ); fileMenu.addSeparator(); fileMenu.add( exitItem ); 273 setSize( 400, 250 ); setVisible( true ); 276 } // end constructor 278 public static void main( String args[] ) { new TransactionProcessor(); } 283 TransactionProcessor.java

106 TransactionProcessor.java Line 309
// get the file name and open the file private boolean openFile() { // display dialog so user can select file JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); 290 int result = fileChooser.showOpenDialog( this ); 292 // if user clicked Cancel button on dialog, return if ( result == JFileChooser.CANCEL_OPTION ) return false; 296 // obtain selected file File fileName = fileChooser.getSelectedFile(); 299 // display error if file name invalid if ( fileName == null || fileName.getName().equals( "" ) ) { JOptionPane.showMessageDialog( this, "Invalid File Name", "Bad File Name", JOptionPane.ERROR_MESSAGE ); return false; } 306 try { // call the helper method to open the file dataFile = new FileEditor( fileName ); } TransactionProcessor.java Line 309 Create a FileEditor object from the file name

107 TransactionProcessor.java Line 323 Lines 336-337
311 catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error Opening File", "IO Error", JOptionPane.ERROR_MESSAGE ); return false; } 317 return true; 319 } // end method openFile 321 // create, update or delete the record private void performAction( String action ) { try { 326 // get the textfield values String[] values = userInterface.getFieldValues(); 329 int accountNumber = Integer.parseInt( values[ BankUI.ACCOUNT ] ); String firstName = values[ BankUI.FIRSTNAME ]; String lastName = values[ BankUI.LASTNAME ]; double balance = Double.parseDouble( values[ BankUI.BALANCE ] ); 334 if ( action.equals( "Create" ) ) dataFile.newRecord( accountNumber, // create a new record firstName, lastName, balance ); TransactionProcessor.java Line 323 Lines Called when the first action button is pressed Create a new record

108 TransactionProcessor.java Lines 340-341 Line 344
338 else if ( action.equals( "Update" ) ) dataFile.updateRecord( accountNumber, // update record firstName, lastName, balance ); 342 else if ( action.equals( "Delete" ) ) dataFile.deleteRecord( accountNumber ); // delete record 345 else JOptionPane.showMessageDialog( this, "Invalid Action", "Error executing action", JOptionPane.ERROR_MESSAGE ); 349 } // end try 351 catch( NumberFormatException format ) { JOptionPane.showMessageDialog( this, "Bad Input", "Number Format Error", JOptionPane.ERROR_MESSAGE ); } 356 catch( IllegalArgumentException badAccount ) { JOptionPane.showMessageDialog( this, badAccount.getMessage(), "Bad Account Number", JOptionPane.ERROR_MESSAGE ); } catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error writing to the file", "IO Error", JOptionPane.ERROR_MESSAGE ); } Update a record TransactionProcessor.java Lines Line 344 Delete a record

109 TransactionProcessor.java Line 369
365 } // end method performAction 367 // input a record in the textfields and update the balance private void displayRecord( String transaction ) { try { // get the account number int accountNumber = Integer.parseInt( userInterface.getFieldValues()[ BankUI.ACCOUNT ] ); 375 // get the associated record RandomAccessAccountRecord record = dataFile.getRecord( accountNumber ); 379 if ( record.getAccount() == 0 ) JOptionPane.showMessageDialog( this, "Record does not exist", "Bad Account Number", JOptionPane.ERROR_MESSAGE ); 383 // get the transaction double change = Double.parseDouble( transaction ); 386 // create a string array to send to the textfields String[] values = { String.valueOf( record.getAccount() ), record.getFirstName(), record.getLastName(), String.valueOf( record.getBalance() + change ), "Charge(+) or payment (-)" }; TransactionProcessor.java Line 369 Display a record in the textfields

110 TransactionProcessor.java 392
userInterface.setFieldValues( values ); 394 } // end try 396 catch( NumberFormatException format ) { JOptionPane.showMessageDialog( this, "Bad Input", "Number Format Error", JOptionPane.ERROR_MESSAGE ); } 401 catch ( IllegalArgumentException badAccount ) { JOptionPane.showMessageDialog( this, badAccount.getMessage(), "Bad Account Number", JOptionPane.ERROR_MESSAGE ); } 406 catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error reading the file", "IO Error", JOptionPane.ERROR_MESSAGE ); } 411 } // end method displayRecord 413 414 } // end class TransactionProcessor TransactionProcessor.java

111 FileEditor.java Line 15 Line 22
// Fig : FileEditor.java // This class declares methods that manipulate bank account // records in a random access file. import java.io.*; 5 import com.deitel.jhtp5.ch17.RandomAccessAccountRecord; 7 public class FileEditor { 9 RandomAccessFile file; // reference to the file 11 // open the file public FileEditor( File fileName ) throws IOException { file = new RandomAccessFile( fileName, "rw" ); } 17 // close the file public void closeFile() throws IOException { if ( file != null ) file.close(); } 24 FileEditor.java Line 15 Line 22 Create a RandomAccessFile from the file name provided Close the object’s file

112 FileEditor.java Line 26 Line 35 Line 37 Lines 44-45
// get a record from the file public RandomAccessAccountRecord getRecord( int accountNumber ) throws IllegalArgumentException, NumberFormatException, IOException { RandomAccessAccountRecord record = new RandomAccessAccountRecord(); 30 if ( accountNumber < 1 || accountNumber > 100 ) throw new IllegalArgumentException( "Out of range" ); 33 // seek appropriate record in file file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE ); 36 record.read( file ); 38 return record; 40 } // end method getRecord 42 // update record in file public void updateRecord( int accountNumber, String firstName, String lastName, double balance ) throws IllegalArgumentException, IOException { RandomAccessAccountRecord record = getRecord( accountNumber ); if ( accountNumber == 0 ) throw new IllegalArgumentException( "Account does not exist" ); 51 Get a record from the file FileEditor.java Line 26 Line 35 Line 37 Lines 44-45 Position the file pointer Read a record Update a record

113 FileEditor.java Line 53 Line 58 Lines 63-64 Line 73
// seek appropriate record in file file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE ); 54 record = new RandomAccessAccountRecord( accountNumber, firstName, lastName, balance ); 57 record.write( file ); // write updated record to file 59 } // end method updateRecord 61 // add record to file public void newRecord( int accountNumber, String firstName, String lastName, double balance ) throws IllegalArgumentException, IOException { RandomAccessAccountRecord record = getRecord( accountNumber ); 68 if ( record.getAccount() != 0 ) throw new IllegalArgumentException( "Account already exists" ); 71 // seek appropriate record in file file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE ); 74 record = new RandomAccessAccountRecord( accountNumber, firstName, lastName, balance ); Position the file pointer FileEditor.java Line 53 Line 58 Lines Line 73 Overwrite the record Create a new record Position the file pointer

114 FileEditor.java Line 78 Line 83 Line 92 Line 96
77 record.write( file ); // write record to file 79 } // end method newRecord 81 // delete record from file public void deleteRecord( int accountNumber ) throws IllegalArgumentException, IOException { RandomAccessAccountRecord record = getRecord( accountNumber ); 87 if ( record.getAccount() == 0 ) throw new IllegalArgumentException( "Account does not exist" ); 90 // seek appropriate record in file file.seek( ( accountNumber - 1 ) * RandomAccessAccountRecord.SIZE ); 93 // create a blank record to write to the file record = new RandomAccessAccountRecord(); record.write( file ); 97 } // end method deleteRecord 99 100 } // end class EditFile Write the new record FileEditor.java Line 78 Line 83 Line 92 Line 96 Delete a record Position the file pointer Delete a record by overwriting the old record with a blank record

115 17.13 New I/O APIs for the Java Platform
Buffers Consolidate I/O operations Four properties Capacity Limit Position Mark Put and get operations Relative or absolute Clear, flip, rewind, reset

116 17.13 New I/O APIs for the Java Platform
Channels Connection to an I/O device Interacts efficiently with buffers ReadableByteChannel interface Method read WriteableByteChannel interface Method write Scattering reads and gather writes Class FileChannel

117 17.13 New I/O APIs for the Java Platform
File Locks Restricts access to a portion of a file FileChannel, position, size Exclusive or shared Charsets Package java.nio.charset Class Charset Methods decode, encode Class CharsetDecoder, CharsetEncoder

118 FileChannelTest.java Lines 4-5 Line 16
// Fig. 17.23: FileChannelTest.java // Demonstrates FileChannel and ByteBuffer. import java.io.*; import java.nio.*; import java.nio.channels.*; 6 public class FileChannelTest { private FileChannel fileChannel; 9 // no-arg constructor public FileChannelTest() { // create random access file and get file channel try { RandomAccessFile file = new RandomAccessFile( "Test", "rw" ); fileChannel = file.getChannel(); } catch ( IOException ioException ) { ioException.printStackTrace(); } 21 } // end constructor FileChannelTest 23 FileChannelTest.java Lines 4-5 Line 16 Import the java.nio and java.nio.channels packages Get a channel by calling method getChannel

119 FileChannelTest.java Line 28 Lines 31-33 Line 36 Line 37 Line 46
// write to writeChannel public void writeToFile() throws IOException { // create buffer for writing ByteBuffer buffer = ByteBuffer.allocate( 14 ); 29 // write an int, a char and a double to buffer buffer.putInt( 100 ); buffer.putChar( 'A' ); buffer.putDouble( ); 34 // flip buffer and write buffer to fileChannel buffer.flip(); fileChannel.write( buffer ); } 39 // read from readChannel public void readFromFile() throws IOException { String content = ""; 44 // create buffer for read ByteBuffer buffer = ByteBuffer.allocate( 14 ); 47 Allocate a buffer of 14 bytes FileChannelTest.java Line 28 Lines Line 36 Line 37 Line 46 Fill the buffer with an integer, a character and a double Flip the buffer to prepare it for writing Write the buffer to the FileChannel Allocate a buffer of 14 bytes

120 FileChannelTest.java Lines 49-50 Line 53 Lines 56-57 Line 62
// read buffer from fileChannel fileChannel.position( 0 ); fileChannel.read( buffer ); 51 // flip buffer for reading buffer.flip(); 54 // obtain content content += buffer.getInt() + ", " + buffer.getChar() + ", " + buffer.getDouble(); 58 System.out.println( "File contains: " + content ); 60 // close fileChannel fileChannel.close(); 63 } // end method readFromFile 65 public static void main( String[] args ) { FileChannelTest application = new FileChannelTest(); 69 Position the FileChannel at the beginning and fill the buffer with bytes FileChannelTest.java Lines Line 53 Lines Line 62 Flip the buffer to prepare it for reading Fill the buffer with an integer, a character and a double Close the FileChannel

121 FileChannelTest.java 70 // write to file and then read from file
try { application.writeToFile(); application.readFromFile(); } catch ( IOException ioException ) { ioException.printStackTrace(); } } 79 80 } // end class FileChannelTest FileChannelTest.java File contains: 100, A, 12.34


Download ppt "Chapter 17 – Files and Streams"

Similar presentations


Ads by Google