300 likes | 462 Views
Exceptions and I/O Streams. Now we can explore two related topics further: exceptions and input/output streams Chapter 8 focuses on: the try-catch statement exception propagation creating and throwing exceptions types of I/O streams Keyboard class processing reading and writing text files.
E N D
Exceptions and I/O Streams • Now we can explore two related topics further: exceptions and input/output streams • Chapter 8 focuses on: • the try-catch statement • exception propagation • creating and throwing exceptions • types of I/O streams • Keyboard class processing • reading and writing text files
Exceptions • An exception is an object that describes an unusual or erroneous situation • Exceptions are thrown by a program, and may be caught and handled by another part of the program • A program can be separated into a normal execution flow and an exception execution flow • An error is also represented as an object in Java, but usually represents a unrecoverable situation and should not be caught
Exception Handling • Java has a predefined set of exceptions and errors that can occur during execution • A program can deal with an exception in one of three ways: • ignore it • handle it where it occurs • handle it an another place in the program • The manner in which an exception is processed is an important design consideration
Exception Handling • If an exception is ignored by the program, the program will terminate abnormally and produce an appropriate message • The message includes a call stack trace that indicates the line on which the exception occurred • The call stack trace also shows the method call trail that lead to the attempted execution of the offending line • The getMessage method returns a string explaining why the exception was thrown • The printStackTrace method prints the call stack trace • See Zero.java
Zero.java //******************************************************************** // Zero.java Author: Lewis and Loftus // // Demonstrates an uncaught exception. //******************************************************************** public class Zero { //----------------------------------------------------------------- // Deliberately divides by zero to produce an exception. //----------------------------------------------------------------- public static void main (String[] args) { int numerator = 10; int denominator = 0; System.out.println (numerator / denominator); System.out.println ("This text will not be printed."); } }
The try Statement • To process an exception when it occurs, the line that throws the exception is executed within a try block • A try block is followed by one or more catch clauses, which contain code to process an exception • Each catch clause has an associated exception type and is called an exception handler • When an exception occurs, processing continues at the first catch clause that matches the exception type • See ProductCodes.java
import cs1.Keyboard; public class ProductCodes { public static void main (String[] args) { String code; char zone; int district, valid = 0, banned = 0; System.out.print ("Enter product code (XXX to quit): "); code = Keyboard.readString(); while (!code.equals ("XXX")) { try { zone = code.charAt(9); district = Integer.parseInt(code.substring(3, 7)); valid++; if (zone == 'R' && district > 2000) banned++; } catch (StringIndexOutOfBoundsException exception) { System.out.println ("Improper code length: " + code); } catch (NumberFormatException exception) { System.out.println ("District is not numeric: " + code); } System.out.print ("Enter product code (XXX to quit): "); code = Keyboard.readString(); } System.out.println ("# of valid codes entered: " + valid); System.out.println ("# of banned codes entered: " + banned); } }
The finally Clause • A try statement can have an optional clause following the catch clauses, designated by the reserved word finally • The statements in the finally clause always are executed • If no exception is generated, the statements in the finally clause are executed after the statements in the try block complete • If an exception is generated, the statements in the finally clause are executed after the statements in the appropriate catch clause complete
Exception Propagation • An exception can be handled at a higher level if it is not appropriate to handle it where it occurs • Exceptions propagate up through the method calling hierarchy until they are caught and handled or until they reach the level of the main method • A try block that contains a call to a method in which an exception is thrown can be used to catch that exception
The throw Statement • A programmer can define an exception by extending the Exception class or one of its descendants • Exceptions are thrown using the throw statement • Usually a throw statement is nested inside an if statement that evaluates the condition to see if the exception should be thrown • See CreatingExceptions.java • See OutOfRangeException.java(page 460)
CreatingExceptions.java import OutOfRangeException; import cs1.Keyboard; public class CreatingExceptions { //----------------------------------------------------------------- // Creates an exception object and possibly throws it. //----------------------------------------------------------------- public static void main (String[] args) throws OutOfRangeException { final int MIN = 25, MAX = 40; OutOfRangeException problem = new OutOfRangeException ("Input value is out of range."); System.out.print ("Enter an integer value between " + MIN + " and " + MAX + ", inclusive: "); int value = Keyboard.readInt(); // Determines if the exception should be thrown if (value < MIN || value > MAX) throw problem; System.out.println ("End of main method."); // may never reach } }
OutOfRangeException.java //******************************************************************** // // Represents an exceptional condition in which a value is out of // some particular range. //******************************************************************** public class OutOfRangeException extends Exception { //----------------------------------------------------------------- // Sets up the exception object with a particular message. //----------------------------------------------------------------- OutOfRangeException (String message) { super (message); } }
Checked Exceptions • An exception is either checked or unchecked • A checked exception either must be caught by a method, or must be listed in the throws clause of any method that may throw or propagate it • A throws clause is appended to the method header • The compiler will issue an error if a checked exception is not handled appropriately
Unchecked Exceptions • An unchecked exception does not require explicit handling, though it could be processed that way • The only unchecked exceptions in Java are objects of type RuntimeException or any of its descendants • Errors are similar to RuntimeException and its descendants • Errors should not be caught • Errors to not require a throws clause
I/O Streams • A stream is a sequence of bytes that flow from a source to a destination • In a program, we read information from an input stream and write information to an output stream • A program can manage multiple streams simultaneously
I/O Streams • The java.io package contains many classes that allow us to define various streams with particular characteristics • Some classes assume that the data consists of characters • Others assume that the data consists of raw bytes of binary information • Streams can be further subdivided as follows: • data stream, which acts as either a source or destination • processing stream, which alters or manipulates the basic data in the stream
Data Streams Processing Streams Input Streams Output Streams Character Streams Byte Streams I/O Streams
Character vs. Byte Streams • A character stream manages 16-bit Unicode characters • A byte stream manages 8-bit bytes of raw binary data • A program must determine how to interpret and use the bytes in a byte stream • Typically they are used to read and write sounds and images • The InputStream and OutputStream classes (and their descendants) represent byte streams • The Reader and Writer classes (and their descendants) represent character streams
Data vs. Processing Streams • A data stream represents a particular source or destination such as a string in memory or a file on disk • A processing stream (also called a filtering stream) manipulates the data in the stream • It may convert the data from one format to another • It may buffer the stream
The IOException Class • Operations performed by the I/O classes may throw an IOException • A file intended for reading or writing might not exist • Even if the file exists, a program may not be able to find it • The file might not contain the kind of data we expect • An IOException is a checked exception
Standard I/O • There are three standard I/O streams: • standard input – defined by System.in • standard output – defined by System.out • standard error – defined by System.err • System.in typically represents keyboard input • System.out and System.err typically represent a particular window on the monitor screen • We use System.out when we execute println statements
The Keyboard Class • The Keyboard class was written by the authors of your textbook to facilitate reading data from standard input • The Keyboard class: • declares a useful standard input stream • handles I/O exceptions that may be thrown • parses input lines into tokens • converts an input value into the expected type • handles conversion problems
The Keyboard Class • The Keyboard class declares the following input stream: InputStreamReader isr = new InputStreamReader (System.in) BufferedReader stdin = new BufferedReader (isr); • The InputStreamReader object converts the original byte stream into a character stream • The BufferedReader object allows us to use the readLine method to get an entire line of input
The Keyboard Class • Each invocation or readLine is performed inside a try block • The Keyboard class uses a StringTokenizer object to extract tokens • The Keyboard class performs type conversions as needed
Text Files • Information can be read from and written to text files by declaring and using the correct I/O streams • The FileReader class represents an input file containing character data • The FileReader and BufferedReader classes together create a convenient text file output stream • See CheckInventory.java(page 468) • See InventoryItem.java(page 470)
InventoryItem.java import java.text.DecimalFormat; public class InventoryItem { private String name; private int units; // number of available units of this item private float price; // price per unit of this item private DecimalFormat fmt; // Sets up this item with the specified information. public InventoryItem (String itemName, int numUnits, float cost) { name = itemName; units = numUnits; price = cost; fmt = new DecimalFormat ("0.##"); } // Returns information about this item as a string. public String toString() { return name + ":\t" + units + " at " + price + " = " + fmt.format ((units * price)); } }
import InventoryItem; import java.util.StringTokenizer; import java.io.*; public class Inventory { public static void main (String[] args) { final int MAX = 100; InventoryItem[] items = new InventoryItem[MAX]; StringTokenizer tokenizer; String line, name, file="inventory.dat"; int units, count = 0; float price; try { FileReader fr = new FileReader (file); BufferedReader inFile = new BufferedReader (fr); line = inFile.readLine(); while (line != null) { tokenizer = new StringTokenizer (line); name = tokenizer.nextToken(); try { units = Integer.parseInt (tokenizer.nextToken()); price = Float.parseFloat(tokenizer.nextToken()); items[count++] = new InventoryItem (name, units, price); } catch (NumberFormatException exception) { System.out.println ("Error in input. Line ignored:"); System.out.println (line); } line = inFile.readLine(); } inFile.close(); for (int scan = 0; scan < count; scan++) System.out.println (items[scan]); } catch (FileNotFoundException exception) { System.out.println ("The file " + file + " was not found."); } catch (IOException exception) { System.out.println (exception); } } }
Text Files • The FileWriter class represents a text output file, but with minimal support for manipulating data • Therefore, the PrintWriter class provides print and println methods • See TestData.java(page 472) • Output streams should be closed explicitly
TestData.java import java.io.*; public class TestData public static void main (String[] args) throws IOException { final int MAX = 10; int value; String file = "test.dat"; FileWriter fw = new FileWriter (file); BufferedWriter bw = new BufferedWriter (fw); PrintWriter outFile = new PrintWriter (bw); for (int line=1; line <= MAX; line++) { for (int num=1; num <= MAX; num++) { value = (int) (Math.random() * 100); outFile.print (value + " "); } outFile.println (); } outFile.close(); System.out.println ("Output file has been created: " + file); } }
WriteCountryInfo.java public class WriteCountryInfo { public static void main (String[] args) throws IOException { FileOutputStream file = new FileOutputStream ("countries.dat"); ObjectOutputStream outStream = new ObjectOutputStream (file); CountryInfo[] countries = new CountryInfo[5]; countries[0] = new CountryInfo ("United States of America", "USA", "Washington, D.C.", 9629091L, 278058900L); countries[1] = new CountryInfo ("Russia", "RUS", "Moscow", 17075200L, 145470200L); countries[2] = new CountryInfo ("Italy", "ITA", "Rome", 301230L, 57679800L); countries[3] = new CountryInfo ("Sweden", "SWE", "Stockholm", 449964L, 8875100L); countries[4] = new CountryInfo ("Poland", "POL", "Warsaw", 312685L, 38633900L); int scan; for (scan = 0; scan < countries.length; scan++) System.out.println (countries[scan]); // Serialize the objects to a file for (scan = 0; scan < countries.length; scan++) outStream.writeObject (countries[scan]); } }