Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 121 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
121
Dung lượng
608,5 KB
Nội dung
Chapter 17 – Files and Streams Outline 17.1 Introduction 17.2 Data Hierarchy 17.3 Files and Streams 17.4 Class File 17.5 Creating a Sequential-Access File 17.6 Reading Data from a Sequential-Access File 17.7 Updating Sequential-Access Files 17.8 Random-Access Files 17.9 Creating a Random-Access File 17.10 Writing Data Randomly to a Random-Access File 17.11 Reading Data Sequentially from a Random-Access File 17.12 Case Study: A Transaction-Processing Program 17.13 New I/O APIs for the Java Platform 2003 Prentice Hall, Inc All rights reserved 17.1 Introduction • Files – Long-term storage of large amounts of data – Persistent data exists after termination of program – Files stored on secondary storage devices • Magnetic disks • Optical disks • Magnetic tapes – Sequential and random access files 2003 Prentice Hall, Inc All rights reserved 17.2 Data Hierarchy • Smallest data item in a computer is a bit – Bit can be either or – 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 bytes • A byte is bits long • Fields (Java instance variables) – Composed of characters or bytes – Conveys meaning 2003 Prentice Hall, Inc All rights reserved 17.2 Data Hierarchy • Data hierarchy – Data items in a computer form a hierarchy • Progresses from bits, to characters, to fields, etc • Records – Composed of several fields – Implemented as a class in Java – See Fig 17.1 for example • File is a group of related records – One field in each record is a record key • Record key is a unique identifier for a record – Sequential file • Records stored in order by record key 2003 Prentice Hall, Inc All rights reserved Fig 17.1 Data hierarchy Judy Judy 01001010 Bit 2003 Prentice Hall, Inc All rights reserved Sally Black Tom Blue Judy Green Iris Orange Randy Red Green File Record Field Byte (ASCII character J) 17.3 Files and Streams • Java views a file as a stream of bytes (Fig 17.2) – File ends with end-of-file marker or a specific byte number – File as a stream of bytes associated with an object • Java also associates streams with devices – System.in, System.out, and System.err – Streams can be redirected • File processing with classes in package java.io – – – – FileInputStream for byte-based input from a file FileOutputStream for byte-based output to a file FileReader for character-based input from a file FileWriter for character-based output to a file 2003 Prentice Hall, Inc All rights reserved Fig 17.2 Java’s view of a file of n bytes 2003 Prentice Hall, Inc All rights reserved n-1 end-of-file marker 17.3 Files and Streams • Buffering – Improves performance of I/O – Copies each output to a region of memory called a buffer – Entire buffer output to disk at once • One long disk access takes less time than many smaller ones – BufferedOutputStream buffers file output – BufferedInputStream buffers file input 2003 Prentice Hall, Inc All rights reserved 17.4 Class File • Class File – Provides useful information about a file or directory – Does not open files or process files • Fig 17.3 lists some useful File methods 2003 Prentice Hall, Inc All rights reserved 10 Fig 17.3 File methods Method boolean canRead() Description Returns true if a file is readable; false otherwise boolean canWrite() boolean exists() Returns true if a file is writable; false otherwise Returns true if the name specified as the argument to the File constructor is a file or directory in the specified path; false otherwise boolean isFile() Returns true if the name specified as the argument to the File constructor is a file; false otherwise Returns true if the name specified as the argument to the File constructor is a directory; false otherwise Returns true if the arguments specified to the File constructor indicate an absolute path to a file or directory; false otherwise boolean isDirectory() boolean isAbsolute() String getAbsolutePath() Returns a string with the absolute path of the file or directory String getName() String getPath() String getParent() Returns a string with the name of the file or directory Returns a string with the path of the file or directory Returns a string with the parent directory of the file or directory—that is, the directory in which the file or directory can be found long length() Returns the length of the file, in bytes If the File object represents a directory, is returned Returns a platform-dependent representation of the time at which the file or directory was last modified The value returned is useful only for comparison with other values returned by this method long lastModified() String[] list() 2003 Prentice Hall, Inc All rights reserved Returns an array of strings representing the contents of a directory Returns null if the File object is not a directory 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error Opening File", "IO Error", JOptionPane.ERROR_MESSAGE ); return false; } return true; } // end method openFile // create, update or delete the record private void performAction( String action ) { try { Outline TransactionProc essor.java Line 323 Called when the first Lines action336-337 button is pressed // get the textfield values String[] values = userInterface.getFieldValues(); int accountNumber = Integer.parseInt( values[ BankUI.ACCOUNT ] ); String firstName = values[ BankUI.FIRSTNAME ]; String lastName = values[ BankUI.LASTNAME ]; double balance = Double.parseDouble( values[ BankUI.BALANCE ] ); Create a new record if ( action.equals( "Create" ) ) dataFile.newRecord( accountNumber, // create a new record firstName, lastName, balance ); 2003 Prentice Hall, Inc All rights reserved 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 else if ( action.equals( "Update" ) ) dataFile.updateRecord( accountNumber, // update record firstName, lastName, balance ); else if ( action.equals( "Delete" ) ) dataFile.deleteRecord( accountNumber ); // delete record else JOptionPane.showMessageDialog( this, "Invalid Action", "Error executing action", JOptionPane.ERROR_MESSAGE ); Outline Update a record TransactionProc essor.java Delete a record Lines 340-341 Line 344 } // end try catch( NumberFormatException format ) { JOptionPane.showMessageDialog( this, "Bad Input", "Number Format Error", JOptionPane.ERROR_MESSAGE ); } catch( IllegalArgumentException badAccount ) { JOptionPane.showMessageDialog( this, badAccount.getMessage(), "Bad Account Number", JOptionPane.ERROR_MESSAGE ); } catch( IOException ioException ) { JOptionPane.showMessageDialog( this, "Error writing to the file", "IO Error", JOptionPane.ERROR_MESSAGE ); } 2003 Prentice Hall, Inc All rights reserved 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 } // end method performAction // input a record in the textfields and update the balance private void displayRecord( String transaction ) { try { // get the account number int accountNumber = Integer.parseInt( userInterface.getFieldValues()[ BankUI.ACCOUNT ] ); // get the associated record RandomAccessAccountRecord record = dataFile.getRecord( accountNumber ); Outline TransactionProc essor.java Line 369 Display a record in the textfields if ( record.getAccount() == ) JOptionPane.showMessageDialog( this, "Record does not exist", "Bad Account Number", JOptionPane.ERROR_MESSAGE ); // get the transaction double change = Double.parseDouble( transaction ); // create a string array to send to the textfields String[] values = { String.valueOf( record.getAccount() ), record.getFirstName(), record.getLastName(), String.valueOf( record.getBalance() + change ), "Charge(+) or payment (-)" }; 2003 Prentice Hall, Inc All rights reserved 392 393 userInterface.setFieldValues( values ); 394 395 } // end try 396 397 catch( NumberFormatException format ) { 398 JOptionPane.showMessageDialog( this, "Bad Input", 399 "Number Format Error", JOptionPane.ERROR_MESSAGE ); 400 } 401 402 catch ( IllegalArgumentException badAccount ) { 403 JOptionPane.showMessageDialog( this, badAccount.getMessage(), 404 "Bad Account Number", JOptionPane.ERROR_MESSAGE ); 405 } 406 407 catch( IOException ioException ) { 408 JOptionPane.showMessageDialog( this, "Error reading the file", 409 "IO Error", JOptionPane.ERROR_MESSAGE ); 410 } 411 412 } // end method displayRecord 413 414 } // end class TransactionProcessor Outline TransactionProc essor.java 2003 Prentice Hall, Inc All rights reserved 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 // Fig 17.22: FileEditor.java // This class declares methods that manipulate bank account // records in a random access file import java.io.*; import com.deitel.jhtp5.ch17.RandomAccessAccountRecord; Outline FileEditor.java Line 15 public class FileEditor { RandomAccessFile file; // reference to the file // open the file public FileEditor( File fileName ) throws IOException { file = new RandomAccessFile( fileName, "rw" ); } // close the file public void closeFile() throws IOException { if ( file != null ) file.close(); } Line 22 Create a RandomAccessFile from the file name provided Close the object’s file 2003 Prentice Hall, Inc All rights reserved 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 // get a record from the file public RandomAccessAccountRecord getRecord( int accountNumber ) throws IllegalArgumentException, NumberFormatException, IOException { RandomAccessAccountRecord record = new RandomAccessAccountRecord(); if ( accountNumber < || accountNumber > 100 ) throw new IllegalArgumentException( "Out of range" ); // seek appropriate record in file file.seek( ( accountNumber - ) * RandomAccessAccountRecord.SIZE ); record.read( file ); return record; Outline FileEditor.java Get a record Line 26 from the file Line 35 Position the file Line 37 pointer Lines 44-45 Read a record } // end method getRecord // update record in file public void updateRecord( int accountNumber, String firstName, String lastName, double balance ) throws IllegalArgumentException, IOException { RandomAccessAccountRecord record = getRecord( accountNumber ); if ( accountNumber == ) throw new IllegalArgumentException( "Account does not exist" ); Update a record 2003 Prentice Hall, Inc All rights reserved 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 // seek appropriate record in file file.seek( ( accountNumber - ) * RandomAccessAccountRecord.SIZE ); record = new RandomAccessAccountRecord( accountNumber, firstName, lastName, balance ); FileEditor.java Line Position the53 file pointer Line 58 record.write( file ); // write updated record to file } // end method updateRecord // add record to file public void newRecord( int accountNumber, String firstName, String lastName, double balance ) throws IllegalArgumentException, IOException { RandomAccessAccountRecord record = getRecord( accountNumber ); Outline Overwrite the record Lines 63-64 Line 73 Create a new record if ( record.getAccount() != ) throw new IllegalArgumentException( "Account already exists" ); // seek appropriate record in file file.seek( ( accountNumber - ) * RandomAccessAccountRecord.SIZE ); Position the file pointer record = new RandomAccessAccountRecord( accountNumber, firstName, lastName, balance ); 2003 Prentice Hall, Inc All rights reserved Outline 77 78 record.write( file ); // write record to file 79 80 } // end method newRecord FileEditor.java 81 82 // delete record from file Write the new Line 78record 83 public void deleteRecord( int accountNumber ) 84 throws IllegalArgumentException, IOException 85 { Linea 83 Delete record 86 RandomAccessAccountRecord record = getRecord( accountNumber ); 87 Line 92 88 if ( record.getAccount() == ) 89 throw new IllegalArgumentException( "Account does not exist" ); Line 96 90 91 // seek appropriate record in file Position the file 92 file.seek( ( accountNumber - ) * RandomAccessAccountRecord.SIZE ); pointer 93 94 // create a blank record to write to the file 95 record = new RandomAccessAccountRecord(); 96 record.write( file ); Delete a record by 97 overwriting the old record 98 } // end method deleteRecord 99 with a blank record 100 } // end class EditFile 2003 Prentice Hall, Inc All rights reserved 17.13 New I/O APIs for the Java Platform • Buffers – Consolidate I/O operations – Four properties • • • • Capacity Limit Position Mark – Put and get operations • Relative or absolute – Clear, flip, rewind, reset 2003 Prentice Hall, Inc All rights reserved 115 17.13 New I/O APIs for the Java Platform • Channels – Connection to an I/O device • Interacts efficiently with buffers – ReadableByteChannel interface • Method read – WriteableByteChannel interface • Method write – Scattering reads and gather writes – Class FileChannel 2003 Prentice Hall, Inc All rights reserved 116 17.13 New I/O APIs for the Java Platform • File Locks – Restricts access to a portion of a file – FileChannel, position, size – Exclusive or shared • Charsets – Package java.nio.charset • Class Charset – Methods decode, encode • Class CharsetDecoder, CharsetEncoder 2003 Prentice Hall, Inc All rights reserved 117 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // Fig. 17.23: FileChannelTest.java // Demonstrates FileChannel and ByteBuffer import java.io.*; import java.nio.*; import java.nio.channels.*; public class FileChannelTest { private FileChannel fileChannel; // no-arg constructor public FileChannelTest() { // create random access file and get file channel try { RandomAccessFile file = new RandomAccessFile( "Test", "rw" ); fileChannel = file.getChannel(); } catch ( IOException ioException ) { ioException.printStackTrace(); } Outline FileChannelTest Import the java.nio and java java.nio.channels packages Lines 4-5 Line 16 Get a channel by calling method getChannel } // end constructor FileChannelTest 2003 Prentice Hall, Inc All rights reserved 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 // write to writeChannel public void writeToFile() throws IOException { // create buffer for writing ByteBuffer buffer = ByteBuffer.allocate( 14 ); // write an int, a char and a double to buffer buffer.putInt( 100 ); buffer.putChar( 'A' ); buffer.putDouble( 12.34 ); // flip buffer and write buffer to fileChannel buffer.flip(); fileChannel.write( buffer ); } // read from readChannel public void readFromFile() throws IOException { String content = ""; // create buffer for read ByteBuffer buffer = ByteBuffer.allocate( 14 ); Outline FileChannelTest Allocate a buffer java of 14 bytes Fill the buffer with an Line 28 integer, a character and a double Lines 31-33 Flip the buffer to Line 36 prepare it for writing Line 37 Write the buffer to the Line 46 FileChannel Allocate a buffer of 14 bytes 2003 Prentice Hall, Inc All rights reserved 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 // read buffer from fileChannel fileChannel.position( ); fileChannel.read( buffer ); // flip buffer for reading buffer.flip(); // obtain content content += buffer.getInt() + ", " + buffer.getChar() + ", " + buffer.getDouble(); System.out.println( "File contains: " + content ); // close fileChannel fileChannel.close(); } // end method readFromFile Outline Position the FileChannel FileChannelTest at the beginning java and fill the buffer with bytes Flip the buffer to 49-50 prepare itLines for reading Line 53 Fill the buffer with an integer,Lines a character 56-57and a double Line 62 Close the FileChannel public static void main( String[] args ) { FileChannelTest application = new FileChannelTest(); 2003 Prentice Hall, Inc All rights reserved 70 71 72 73 74 75 76 77 78 79 80 // write to file and then read from file try { application.writeToFile(); application.readFromFile(); } catch ( IOException ioException ) { ioException.printStackTrace(); } Outline FileChannelTest java } } // end class FileChannelTest File contains: 100, A, 12.34 2003 Prentice Hall, Inc All rights reserved ... Fig. 17.4: FileTest .java // Demonstrating the File class import java. awt.*; import java. awt.event.*; import java. io.*; import javax.swing.*; Outline FileTest .java Import java. io package Line... digits: ( 0-9 ) Letters: (A-Z and a-z) Special symbols: (e.g., $, @, %, &, *, (, ), -, +, “, :, ?, /, etc.) Java uses Unicode characters composed of bytes • A byte is bits long • Fields (Java instance... 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