50
Lecture 7 Exceptions and I/O

Lecture7 - Copy

Embed Size (px)

Citation preview

Page 1: Lecture7 - Copy

Lecture 7Exceptions and I/O

Page 2: Lecture7 - Copy

Overview of the exception hierarchyA simplified diagram of the exception hierarchy in Java

Throwable

Error Exception

IOException RuntimeException

All exceptions extend the class Throwable, which immediately splits into two branches: Error and Exception Error: internal errors and resource exhaustion inside the Java

runtime system. Little you can do. Exception: splits further into two branches.

Page 3: Lecture7 - Copy

Focus on the Exception branch Two branches of Exception

exceptions that derived from RuntimeException examples: a bad cast, an out-of-array access happens because errors exist in your program. Your fault.

those not in the type of RuntimeException example: trying to open a malformed URL program is good, other bad things happen. Not your fault.

Checked exceptions vs. unchecked exceptions Unchecked exceptions: exceptions derived from the class Error or the

class RuntimeException Checked exceptions: all other exceptions that are not unchecked

exceptions If they occur, they must be dealt with in some way. The compiler will check whether you provide exception handlers for checked

exceptions which may occur

Page 4: Lecture7 - Copy

Declaring to throw checked exceptions A java method or constructor should be declared to throw

exceptions under two situations:1. It calls another method that throws a checked exception2. It throws a checked exception with the throw statement inside its body

Declare a method or constructor to throw an exception (or exceptions) by using throws clause in its header

E.gSingle exception:public FileInputStream(String s) throws FileNotFoundException

Multiple exception:public Image load(String s) throws EOFException, IOException

You should NOT declare an unchecked exception after throws! They are either outside of your control, or should be avoid completely by correcting your code.

Page 5: Lecture7 - Copy

Using throw to throw an exception Throw an exception under some bad situations

E.g: a method named readData is reading a file whose header says it contains 700 characters, but it encounters the end of the file after 200 characters. You decide to throw an exception when this bad situation happens by using the throw statement

throw (new EOFException());or,

EOFException e = new EOFException();throw e;

the entire method will beString readData(Scanner in) throws EOFException { . . . while(. . .) {

if (!in.hasNext()) //EndOfFile encountered {

if(n < len) throw (new EOFException()); } . . .

} return s; }}

Page 6: Lecture7 - Copy

Using throw to throw an exception (cont.)

In the method body you can only throw exceptions which are of the same type or the subtype of the exceptions declared after throws in the method header

If you can find an appropriate exception class in the library, make an object of that class and throw it; otherwise, you design your own exception class

Page 7: Lecture7 - Copy

Creating new exception types Exceptions are objects. New exception types should extend

Exception or one of its subclasses Why creating new exception types?

1. describe the exceptional condition in more details than just the string that Exception provides

2. the type of the exception is an important part of the exception data – programmers need to do some actions exclusively to one type of exception conditions, not others

E.g. suppose there is a method to update the current value of a named attribute of an object, but the object may not contain such an attribute currently. We want an exception to be thrown to indicate the occurring of if such a situationpublic class NoSuchAttributeException extends Exception { public String attrName; public NoSuchAttributeException (String name) {

super(“No attribute named \”” + name + “\” found”);attrName = name;

}}

Page 8: Lecture7 - Copy

Catching exceptions Checked exceptions handling is strictly enforced. If you invoke a

method that lists a checked exception in its throws clause, you have three choices

1. Catch the exception and handle it

2. Declare the exception in your own throws clause, and let the exception pass through your method (you may have a finally clause to clean up first)

3. Catch the exception and map it into one of your exceptions by throwing an exception of a type declared in your own throws clause

Page 9: Lecture7 - Copy

try/catch clause (1) Basic syntax of try/catch block

try { statements} catch(exceptionType1 identifier1) { handler for type1} catch(exceptionType2 identifier1) { handler for type2} . . .

If no exception occurs during the execution of the statements in the try clause, it finishes successfully and all the catch clauses are skipped

If any of the code inside the try block throws an exception, either directly via a throw or indirectly by a method invoked inside it

1. The program skips the remainder of the code in the try block2. The catch clauses are examined one by one, to see whether the type of the

thrown exception object is compatible with the type declared in the catch. 3. If an appropriate catch clause is found, the code inside its body gets

executed and all the remaining catch clauses are skipped. 4. If no such a catch clause is found, then the exception is thrown into an

outer try that might have a catch clause to handle it A catch clause with a superclass exceptionType cannot precede a

catch clause with a subclass exceptionType

Page 10: Lecture7 - Copy

try/catch clause (2) Example

public void read(String fileName) { try { InputStream in = new FileInputStream(fileName); int b;

//the read() method below is one which will throw an IOException while ((b = in.read()) != -1) {

process input } } catch (IOException e) { exception.printStackTrace(); }

}another choice for this situation is to do nothing but simply pass the exception on to the caller of the method public void read(String fileName) throws IOException {

InputStream in = new FileInputStream(fileName); int b; while ((b = in.read()) != -1) {

process input }

} If you call a method that throws a checked exception, you must either handle it or

pass it on. Check the Java API documentation to see what exceptions will be thrown!

Page 11: Lecture7 - Copy

try/catch clause (3) You can throw an exception in a catch clause. Typically you do this

because you want to change the exception type to indicate the failure of your subsystem

try { access the database} catch (SQLException e) { Throwable se = new ServletException(“database error”); se.setCause(e); throw se; }

When the exception is caught, the original exception can be retrieved. This chaining technique allows you to throw high-level exceptions in subsystems without losing details of the original failureThowable e = se.getCause();

Page 12: Lecture7 - Copy

finally clause (1) You may want to do some actions whether or not an exception is

thrown. finally clause does this for youGraphics g = image.getGraphics();try { //1 code that might throw exceptions //2} catch (IOException e) { //3 show error dialog (// some code which may throw exceptions) //4} finally { g.dispose(); (// some code which will not throw exceptions) //5} //6

No exception is thrown: An exception is thrown and caught by the catch clause

The catch clause doesn’t throw any other exception: The catch clause throws an exception itself: , and the exception is

thrown back to the caller of this method An exception is thrown but not caught by the catch clause: , and

the exception is thrown back to the caller of this method

1, 2, 5, 6

1, 3, 4, 5, 61, 3, 5

1, 5

Page 13: Lecture7 - Copy

finally clause (2)

You can use a finally clause without a catch clause Sometimes the finally clause can also thrown an exception

Example

public boolean searchFor(String file, String word) throws StreamException {

Stream input = null;try { some code which may throw an StreamException} finally { input.close(); // this may throw an IOException}

} If the try clause throws a StreamException and the finally clause

throws an IOException, the original exception is lost and the IOException is thrown out instead – a situation you’d better avoid

Page 14: Lecture7 - Copy

The I/O package - overview The java.io package defines I/O in terms of streams – ordered

sequences of data that have a source (input streams) or a destination (output streams)

Two major parts: 1. byte streams

8 bits, data-based input streams and output streams

2. character streams 16 bits, text-based readers and writers

Check out Java API documentation for details about java.io

Page 15: Lecture7 - Copy

Byte streams Two parent abstract classes: InputStream and OutputStream Reading bytes:

InputStream class defines an abstract methodpublic abstract int read() throws IOException

Designer of a concrete input stream class overrides this method to provide useful functionality.

E.g. in the FileInputStream class, the method reads one byte from a file InputStream class also contains nonabstract methods to read an

array of bytes or skip a number of bytes Writing bytes:

OutputStream class defines an abstract methodpublic abstract void write(int b) throws IOException

OutputStream class also contains nonabstract methods for tasks such as writing bytes from a specified byte array

Close the stream after reading of writing to it to free up limited operating system resources by using close()

Page 16: Lecture7 - Copy

Example code1: import java.io.*;class CountBytes {

public static void main(String[] args) throws IOException { FileInputStream in = new FileInputStream(args[0]); int total = 0; while (in.read() != -1) total++; in.close(); System.out.println(total + ” bytes”);}

}

Example code2: import java.io.*;class TranslateByte { public static void main(String[] args) throws IOException { byte from = (byte)args[0].charAt(0); byte to = (byte)args[1].charAt(0); int x; while((x = System.in.read()) != -1) System.out.write(x == from ? to : x);

}}

If you run “java TranslateByte b B” and enter text bigboy via the keyboard the output will be: BigBoy!

Page 17: Lecture7 - Copy

Character streams Two parent abstract classes for characters: Reader and

Writer. Each support similar methods to those of its byte stream counterpart–InputStream and OutputStream, respectively

The standard streams—System.in, System.out and System.err—existed before the invention of character streams. So they are byte streams though logically they should be character streams.

Page 18: Lecture7 - Copy

Conversion between byte and character streams The conversion streams InputStreamReader and

OutputStreamReader translate between Unicode and byte streams public InputStreamReader(InputStream in) public InputStreamReader(InputStream in, String encoding) public OutputStreamWriter(OutputStream out) public OutputStreamWriter(OutputStream out, String encoding)

read method of InputStreamReader read bytes from their associated InputStream and convert them to characters using the appropriate encoding for that stream

write method of OutputStreamWriter take the supplied characters, convert them to bytes using the appropriate encoding and write them to its associated OutputStream

Closing the conversion stream also closes the associated byte stream – may not always desirable

Page 19: Lecture7 - Copy

Working with files

Sequential-Access file: the File streams—FileInputStream, FileOutputStream, FileReader and FileWriter—allow you to treat a file as a stream to input or output sequentially Each file stream type has three types of constructors

A constructor that takes a String which is the name of the file A constructor that take a File object which refers to the file A constructor that takes a FileDescriptor object

Random-Access file: RandomAccessFile allow you to read/write data beginning at the a specified location a file pointer is used to guide the starting position It’s not a subclass of InputStream, OutputStream, Reader or

Writer because it supports both input and output with both bytes and characters

Page 20: Lecture7 - Copy

Example of RandomAccessFileimport java.io.*;class Filecopy { public static void main(String args[]) { RandomAccessFile fh1 = null; RandomAccessFile fh2 = null; long filesize = -1; byte[] buffer1; try { fh1 = new RandomAccessFile(args[0], “r”); fh2 = new RandomAccessFile(args[1], “rw”); } catch (FileNotFoundException e) { System.out.println(“File not found”); System.exit(100); } try { filesize = fh1.length(); int bufsize = (int)filesize/2; buffer1 = new byte[bufsize]; fh1.readFully(buffer1, 0, bufsize); fh2.write(buffer1, 0, bufsize); } catch (IOException e) { System.out.println("IO error occurred!"); System.exit(200); } }}

Page 21: Lecture7 - Copy

The File class The File class is particularly useful for retrieving information about a

file or a directory from a disk. A File object actually represents a path, not necessarily an underlying file A File object doesn’t open files or provide any file-processing capabilities

Three constructors public File( String name) public File( String pathToName, String name) public File( File directory, String name)

Main methods boolean canRead() / boolean canWrite() boolean exists() boolean isFile() / boolean isDirectory() / boolean

isAbsolute() String getAbsolutePath() / String getPath() String getParent() String getName() long length() long lastModified()

Page 22: Lecture7 - Copy

Add more efficiency

BufferedReader reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.

BufferedReader (Reader in)

For example:

to wrap an InputStreamReader inside a BufferedReader BufferedReader in

= new BufferedReader(new InputStreamReader(System.in));

to wrap a FileReader inside a BufferedReader

BufferedReader in = new BufferedReader(new FileReader(“fileName”));

then you can invoke in.readLine() to read from the file line by line

Page 23: Lecture7 - Copy

import java.io.*;public class EfficientReader { public static void main (String[] args) {

try { BufferedReader br = new BufferedReader(new FileReader(args[0]));

// get line String line = br.readLine();

// while not end of file… keep reading and displaying lines while (line != null) { System.out.println("Read a line:"); System.out.println(line); line = br.readLine(); } // close stream br.close(); } catch(FileNotFoundException fe) { System.out.println("File not found: “+ args[0]"); } catch(IOException ioe) { System.out.println("Can’t read from file: “+args[0]); } }}

Page 24: Lecture7 - Copy

Streams, Files and I/O

The java.io package contains nearly every class you might ever need to perform input and output (I/O) in Java. All these streams represent an input source and an output destination. The stream in the java.io package supports many data such as primitives, Object, localized characters etc.

A stream can be defined as a sequence of data. The InputStream is used to read data from a source and the OutputStream is used for writing data to a destination.

Java does provide strong, flexible support for I/O as it relates to files and networks.

Page 25: Lecture7 - Copy

Reading Console Input

Java input console is accomplished by reading from System.in. To obtain a character-based stream that is attached to the console, you wrap System.in in a BufferedReader object, to create a character stream. Here is most common syntax to obtain BufferedReader

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

Page 26: Lecture7 - Copy

Once BufferedReader is obtained, we can use read( ) method to reach a character or readLine( ) method to read a string from the console.

Reading Characters from Console

To read a character from a BufferedReader, we would read( ) method whose sytax is as follows:

int read( ) throws IOException

Page 27: Lecture7 - Copy

Each time that read( ) is called, it reads a character from the input stream and returns it as an integer value. It returns .1 when the end of the stream is encountered. As you can see, it can throw an IOException.

The following program demonstrates read( ) by reading characters from the console until the user types a "q":

Page 28: Lecture7 - Copy

import java.io.*; class BRRead { public static void main(String args[]) throws IOException { char c; // Create a BufferedReader using System.in BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Enter characters, 'q' to quit."); // read characters do { c = (char) br.read(); System.out.println(c); } while(c != 'q'); } }

Page 29: Lecture7 - Copy

Enter characters, 'q' to quit. 123abcq 1 2 3 a b c q

Page 30: Lecture7 - Copy

Reading Strings from Console:

To read a string from the keyboard, use the version of readLine( ) that is a member of the BufferedReader class. Its general form is shown here:

String readLine( ) throws IOException

The following program demonstrates BufferedReader and the readLine( ) method. The program reads and displays lines of text until you enter the word "end":

Page 31: Lecture7 - Copy

// Read a string from console using a BufferedReader. import java.io.*; class BRReadLines { public static void main(String args[]) throws IOException { // Create a BufferedReader using System.in BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Enter lines of text."); System.out.println("Enter 'end' to quit."); do { str = br.readLine(); System.out.println(str); } while(!str.equals("end")); } }

Page 32: Lecture7 - Copy

Enter lines of text. Enter 'end' to quit. This is line one This is line one This is line two This is line two end end

Page 33: Lecture7 - Copy

Writing Console Output:

Console output is most easily accomplished with print( ) and println( ), described earlier. These methods are defined by the class PrintStream which is the type of the object referenced by System.out. Even though System.out is a byte stream, using it for simple program output is still acceptable.

Because PrintStream is an output stream derived from OutputStream, it also implements the low-level method write( ). Thus, write( ) can be used to write to the console. The simplest form of write( ) defined by PrintStream is shown here:

void write(int byteval)

Page 34: Lecture7 - Copy

This method writes to the stream the byte specified by byteval. Although byteval is declared as an integer, only the low-order eight bits are written.

import java.io.*;

// Demonstrate System.out.write(). class WriteDemo { public static void main(String args[]) { int b; b = 'A'; System.out.write(b); System.out.write('\n'); } }

Page 35: Lecture7 - Copy

This would produce simply 'A' character on the output screen.

A

Note: You will not often use write( ) to perform console output because print( ) and println( ) are substantially easier to use.

Page 36: Lecture7 - Copy

Reading and Writing Files:

As described earlier, A stream can be defined as a sequence of data. The InputStream is used to read data from a source and the OutputStream is used for writing data to a destination.

Here is a hierarchy of classes to deal with Input and Output streams.

Page 37: Lecture7 - Copy
Page 38: Lecture7 - Copy

FileInputStream:

This stream is used for reading data from the files. Objects can be created using the keyword new and there are several types of constructors available.

Following constructor takes a file name as a string to create an input stream object to read the file.:

InputStream f = new FileInputStream("C:/java/hello");

Page 39: Lecture7 - Copy

Following constructor takes a file object to create an input stream object to read the file. First we create a file object using File() method as follows:

File f = new File("C:/java/hello"); InputStream f = new FileInputStream(f);

Once you have InputStream object in hand then there is a list of helper methods which can be used to read to stream or to do other operations on the stream.

Page 40: Lecture7 - Copy

1 public void close() throws IOException{}This method closes the file output stream. Releases any system resources associated

with the file. Throws an IOException.

2 protected void finalize()throws IOException {}This method cleans up the connection to the file. Ensures that the close method of this

file output stream is called when there are no more references to this stream. Throws an IOException.

3 public int read(int r)throws IOException{}This method reads the specified byte of data from the InputStream. Returns an int.

Returns the next byte of data and -1 will be returned if it's end of file.

Page 41: Lecture7 - Copy

4 : public int read(byte[] r) throws IOException{}This method reads r.length bytes from the input stream into an array. Returns the total number of bytes read. If end of file -1 will be returned.

5 : public int available() throws IOException{}Gives the number of bytes that can be read from this file input stream. Returns an int.

Page 42: Lecture7 - Copy

4 public int read(byte[] r) throws IOException{}This method reads r.length bytes from the input stream into an array. Returns the total

number of bytes read. If end of file -1 will be returned.

5 public int available() throws IOException{}Gives the number of bytes that can be read from this file input stream. Returns an int.

Page 43: Lecture7 - Copy

There are other important input streams available, for more detail you can refer to the following links:

ByteArrayInputStream DataInputStream

Page 44: Lecture7 - Copy

FileOutputStream

FileOutputStream is used to create a file and write data into it.The stream would create a file, if it doesn't already exist, before opening it for output.

Here are two constructors which can be used to create a FileOutputStream object.

Following constructor takes a file name as a string to create an input stream object to write the file.:

OutputStream f = new FileOutputStream("C:/java/hello")

Page 45: Lecture7 - Copy

Following constructor takes a file object to create an output stream object to write the file. First we create a file object using File() method as follows:

File f = new File("C:/java/hello"); OutputStream f = new FileOutputStream(f);

Page 46: Lecture7 - Copy

Once you have OutputStream object in hand then there is a list of helper methods which can be used to write to stream or to do other operations on the stream.

1 public void close() throws IOException{}This method closes the file output stream. Releases any system resources associated with the file.

Throws an IOException.2 protected void finalize()throws IOException {}This method cleans up the connection to the file. Ensures that the close method of this file output

stream is called when there are no more references to this stream. Throws an IOException.3 public void write(int w)throws IOException{}This methods writes the specified byte to the output stream.4 public void write(byte[] w)Writes w.length bytes from the mentioned byte array to the OutputStream.

Page 47: Lecture7 - Copy

There are other important output streams available, for more detail you can refer to the following links:

ByteArrayOutputStream

DataOutputStream

Page 48: Lecture7 - Copy

Following is the example to demonstrate InputStream and OutputStream:

import java.io.*; public class fileStreamTest{ public static void main(String args[]){ try{ byte bWrite [] = {11,21,3,40,5}; OutputStream os = new FileOutputStream("C:/test.txt"); for(int x=0; x < bWrite.length ; x++){ os.write( bWrite[x] ); // writes the bytes } os.close();

Page 49: Lecture7 - Copy

InputStream is = new FileInputStream("C:/test.txt"); int size = is.available();

for(int i=0; i< size; i++){ System.out.print((char)is.read() + " "); } is.close(); }catch(IOException e){ System.out.print("Exception"); } } }

Page 50: Lecture7 - Copy

The above code would create file test.txt and would write given numbers in binary format. Same would be output on the stdout screen.

File Navigation and I/O:

There are several other classes that we would be going through to get to know the basics of File Navigation and I/O.

File Class FileReader Class FileWriter Class