Lecture 14 April 3, 2017 Note->The lecture accompanying these notes should show you how to: * determine if a constructor or method throws an exception * determine if an exception is checked or unchecked * declare, instantiate, and use file readers and file writers ____ File I/O and exception handling Most interesting programs require more input than a user cares to enter in one sitting. Therefore, most data is read in the form of a file, either a text file (unicode characters) or a binary file to which objects have been written in machine-readable form. We study exceptions along with file input/output because the exceptions associated with these classes were designated by the creators of Java as "checked exceptions" (exceptions that must be noted at compile time.) An exception is an object, which is created during the execution of a program, that disrupts the normal flow of the program's instructions. (Read more at http://download.oracle.com/javase/tutorial/essential /exceptions/) Exceptions fall into 2 different hierarchies: 1. Unchecked Exceptions (subclasses of RunTimeException): You usually don't catch unchecked exceptions. Instead, you fix your program so it can't produce one of these. Example: ArrayIndexOutOfBoundsException, NullPointerException. 2. Checked Exceptions (subclasses of Exception): These are usually errors in the input data or pertaining to the input or output file. The programmer has no control over the input the user gives you for file names. If the user gives you a bad value, it may cause an exception at run time. Checked exceptions are subject to the "Catch or Throw Requirement". This means that code that might throw checked exceptions must be enclosed by either of the following: * A try statement that catches the exception. The try must provide a handler for the exception, as described below in Catching Exceptions. * A method that specifies that it throws the exception. The method must provide a throws clause in the header line that lists the exception, as described below in Specifying the Exceptions Thrown by a Method. ____ Catching Exceptions:____ Two main components: the try and catch blocks. 1. Enclose statements that might throw a checked exception in a try block. 2. Immediately after the try block, include a catch statement to react to specific exceptions or to a superclass of exceptions. ____Creating text files:____ 1. Use any text editor (DrJava will work too, just don't save file with .java extension). 2. Type in text. 3. Save the file as .txt ____ Reading from text files:____ Using the Reader class BufferedReader: 1. Import java.io.* for exceptions and readers. 2. Declare a BufferedReader to be either a local or instance variable. 3. Instantiate the BufferedReader inside a while loop to keep trying in case an exception is thrown: /** * Declares and instantiates a file after a file name is * entered by the user. * @return a BufferedReader set at the top of the file */ private BufferedReader openFileReader() { BufferedReader rd = null; while (rd == null) { try { String name = readLine("Please enter a file name:"); rd = new BufferedReader(new FileReader(name)); } catch (IOException ioe) { println("Unable to open file."); } } return rd; } 4. Read each line from the input file into an ArrayList: /** * Reads all the lines from given BufferedReader into * an ArrayList of Strings. * @param rd BufferedReader * @return a list of Strings containing all lines from * file referenced by rd */ public ArrayList readLineArray(BufferedReader rd) { ArrayList list = new ArrayList(); try { while(true) { // The readLine method in BufferedReader reads all // characters on a line, including the end of line // marker, returning a String (the contents of the line.) String line = rd.readLine(); // When the end of file is reached, readLine returns null if (line == null) { break; } list.add(line); } rd.close(); } catch (IOException ioe) { println("Error reading."); } return list; } In the method listing for the methods in the BufferedReader class, each method specifies the type of exception it may throw by including an @exception or @throws clause in the method header. ____Writing to a Text File____ 1. Import java.io.* for PrintWriter and FileWriter classes 2. Declare and instantiate a PrintWriter variable, either a local or instance variable. try { PrintWriter pr = new PrintWriter(new FileWriter("output.txt")); pr.println("line to write"); pr.close(); } catch (IOException ioe) { println("Error in output."); } If you are writing many lines to a file, you need to put the pr.println statement inside a loop. ___Including a throws clause on a method signature___ Instead of embedding a try/catch statement around exception prone code, you can attach a "throws" clause to the method signature. For the openFileReader method, the signature would look like this: private BufferedReader openFileReader() throws IOException { < rest of code without the try or catch statements > } A different way to deal with exceptions is to include a "throws" clause on the method signature. If the method throws an exception, it gives the method that called it the obligation to either catch the exception or to include a throws clause that sends the exception to its caller, and so on. Eventually the exception is displayed as a stack trace on the user's screen. Throwing exceptions can create problems at times with the acm methods because the signature of the run method cannot end with a throws clause. Therefore,we will not use throws much in this class.