Exception Handling, Files and I/O Streams.

Download Report

Transcript Exception Handling, Files and I/O Streams.

Introduction
• Exception handling
– Exception
• Indication of problem during execution
– E.g., array out of bounds
– Handles errors
– Class Exception
Example
public static int average(int[] a) {
int total = 0;
for(int i = 0; i < a.length; i++) {
total += a[i];
}return total / a.length;
}
What happens when this method is used to take the
average of an array of length zero?
Program throws an Exception and fails
java.lang.ArithmeticException: division by zero
What is an Exception?
• An error event that disrupts the program flow and
may cause a program to fail.
• Some examples:
–
–
–
–
–
–
Performing illegal arithmetic operations
Illegal arguments to methods
Accessing an out-of-bounds array element
Hardware failures
Writing to a read-only file
…
Another Example
public class ExceptionExample {
public static void main(String args[]) {
String[] greek = {"Alpha","Beta"};
System.out.println(greek[2]);
}
}
Output:
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: 2 at
ExceptionExample.main(ExceptionExample.java:4)
Exception Message
• Exception message format
– [exception class]: [additional description of exception]
at [class].[method]([file]:[line number])
• Example
– java.lang.ArrayIndexOutOfBoundsException: 2 at
ExceptionExample.main(ExceptionExample.java:4)
–
–
–
–
–
What exception class?
Which array index is out of bounds?
What method throws the exception?
What file contains the method?
What line of the file throws the exception?
Exception Handling
• Use a try-catch block to handle exceptions
that are thrown
try {
// code that might throw exception
}
catch ([Type of Exception] e) {
// what to do if exception is thrown
}
Exception Handling Example
public static int average(int[] a) {
int total = 0;
for(int i = 0; i < a.length; i++)
total += a[i];
return total / a.length;
}
public static void printAverage(int[] a) {
try {
int avg = average(a);
System.out.println("the average is: " + avg);
}
catch(ArithmeticException e) {
System.out.println("error calculating average");
}
}
Catching Multiple Exceptions
• Handle multiple possible exceptions by multiple
successive catch blocks
try {
// code that might throw multiple exception
}
catch (IOException e) {
// handle IOException and all subclasses
}
catch (ClassNotFoundException e2) {
// handle ClassNotFoundException
}
Exception Terminology
• When an exception happens we say it was thrown
or raised
• When an exception is dealt with, we say the
exception is was handled or caught
Unchecked Exceptions
• All the exceptions we've seen so far have been
Unchecked Exceptions (RuntimeException,
Error, and their subclasses)
• Usually occur because of programming errors,
when code is not robust enough to prevent them
• They are numerous and can sometimes be ignored
by the programmer in the method signature
– methods are not obliged to handle unchecked exceptions
Checked Exceptions
• There are also Checked Exceptions
• Usually occur because of errors programmer
cannot control, e.g.,
– hardware failures,
– unreadable files
• They are less frequent and they cannot be ignored
by the programmer . . .
Dealing with Checked Exceptions
• Every method must catch (handle) checked exceptions or
specify that it may throw them (using the throws keyword)
void readFile1(String filename) {
try {
FileReader reader = new FileReader(filename);
}
catch(FileNotFoundException e){
System.out.println("file was not found");
}
}
or
void readFile2(String filename) throws FileNotFoundException{
FileReader reader = new FileReader(filename);
}
Exception Hierarchy
• All exceptions are instances of classes that are
subclasses of Exception
Checked vs. Unchecked Exceptions
Checked Exceptions
Unchecked Exceptions
Not subclass of
RuntimeException
Subclass of RuntimeException
if not caught, method must
specify it to be thrown
if not caught, method may
specify it to be thrown
for errors that the programmer For errors that the programmer
cannot directly prevent from
can directly prevent from
occurring
occurring
IOException,
FileNotFoundException,
NullPointerException,
IllegalArgumentException,
SocketException,
IllegalStateException,
etc.
etc.
Checked vs. Unchecked Exceptions
• Unchecked exceptions are exceptions that can be
avoided in your code (asking the user to re-enter a
value, using if statements) --usually the result of a
programming error
– Example: Assignment 1 (Add a house to an array)
• Checked are harder to avoid because they usually
don’t have anything to do with your code, so we
need to be more careful with them.
Constructing Exceptions
• Exceptions have at least two constructors:
– no arguments
•
NullPointerException e = new NullPointerException()
– single String argument, descriptive message that
appears when exception error message is printed
• IllegalArgumentExceptione e =new
IllegalArgumentException("number must be positive");
Designing your Own Exception Types
• To write your own exception, write a subclass of
Exception and write both types of constructors
public class MyCheckedException extends IOException{
public MyCheckedException() {}
public MyCheckedException(String m) {
super(m);
}
}
public class MyUncheckedException extends RuntimeException{
public MyUncheckedException() {}
public MyUncheckedException(String m) {
super(m);
}
}
Note that not necessarily a direct subclass
Throwing Exceptions
• Throw exception with the throw keyword
public static int average(int[] a) {
if (a.length == 0) {
throw new IllegalArgumentException("array is empty");
}
int total = 0;
for(int i = 0; i < a.length; i++){
total += a[i];
}
return total / a.length;
}
try {
int[] myInts= {};
System.out.println(average(myInts));
System.out.println("Java is fun");
}
catch (IllegalArgumentException e) {
System.out.println(“array is empty”);
}
or
System.out.println(e.getMessage());
Keyword Summary
• Four new Java keywords
– Try and catch : used to handle exceptions that may be
thrown
– throws: to specify which exceptions a method throws in
method declaration
void readFile2(String filename) throws
FileNotFoundException
– throw: to throw an exception
throw new IllegalArgumentException("array
is empty");
Summary of Java Exception Handling
• A method detects an error and throws an exception
– Exception handler processes the error
• The error is considered caught and handled in this model
• Code that could generate errors put in try blocks
– Code for error handling enclosed in a catch block
• Keyword throws tells exceptions of a method
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
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 normally 8 bits long
• Fields (Java instance variables)
– Composed of characters or bytes
– Conveys meaning
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 the figure on the next slide 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
The data hierarchy.
Files and Streams
• Java views a file as a stream of bytes
– 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
Java’s view of a file of n bytes.
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
– A program can convert a unbuffered stream into a buffered
stream using the wrapping idiom
• Example
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new
FileWriter("characteroutput.txt"));
A portion of the class hierarchy of the
java.io package.
A portion of the class hierarchy of the java.io package
java.lang.Object
File
FileDescriptor
InputStream
ByteArrayInputStream
FileInputStream
FilterInputStream
BufferedInputStream
DataInputStream
PushbackInputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
OutputStream
ByteArrayOutputStream
FileOutputStream
FilterOutputStream
BufferedOutputStream
DataOutputStream
PrintStream
ObjectOutputStream
PipedOutputStream
A portion of the class hierarchy of the
java.io package (cont.).
RandomAccessFile
Reader
BufferedReader
LineNumberReader
CharArrayReader
FilterReader
PushbackReader
InputStreamReader
FileReader
PipedReader
StringReader
Writer
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
FileWriter
PipedWriter
PrintWriter
StringWriter
import java.text.DecimalFormat;
Example: reading a text file
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;
public InventoryItem (String itemName, int numUnits, float cost) {
name = itemName;
units = numUnits;
price = cost;
fmt = new DecimalFormat ("0.##");
}
public String toString()
{
return name + ":\t" + units + " at " + price + " = " +
fmt.format ((units * price));
}
}
import java.util.StringTokenizer;
import java.io.*;
public class Inventory{
// Reads data about a store inventory from an input file,
// creating an array of InventoryItem objects, then prints them.
public static void main (String[] args)
{
final int MAX = 100;
InventoryItem[] items = new InventoryItem[MAX];
StringTokenizer tokenizer;
String line, name, file="inventory.txt";
int units, count = 0;
float price;
Example: reading a text file
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();
Example: reading a text file
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);
}
}
}
import java.io.*;
Example: writing a text file
public class TestData {
// Creates a file of test data that consists of ten lines each
// containing ten integer values in the range 0 to 99.
public static void main (String[] args) throws IOException
{
final int MAX = 10;
int value;
String file = "test.txt";
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);
}
}
Data Streams and Object Streams
• Data streams support I/O of primitive data types
• Object streams support I/O of objects
• Most, but not all, standard classes support
serialization of their objects.
– Those classes implement the marker interface
Serializable
– Every instance variable of the class should is a
Serializable
• Object stream classes
– ObjectInputStream and ObjectOutputStream
• Output using the writeObject() method
Updating Sequential-Access File
• 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
Random-Access File
• “Instant-access” applications
– Record must be located immediately
– Transaction-processing systems require rapid access
• Random-access files
– behave like a large array of bytes stored in the file system
– 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
– Figure on the next slide shows random-access file
Java’s view of a random-access file
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
// Record class for the RandomAccessFile programs.
import java.io.*;
public class Record {
private int account;
private String lastName;
private String firstName;
private double balance;
public Record(int a, String f, String l, double b) {
account=a;
firstName=f;
lastName=l;
balance=b;
}
public Record() {
account=0;
firstName=null;
lastName=null;
balance=0;
}
// Read a record from the specified RandomAccessFile
public void read( RandomAccessFile file ) throws IOException
account = file.readInt();
byte b1[] = new byte[ 15 ];
file.readFully( b1 );
firstName = new String( b1 );
firstName=firstName.trim();
byte b2[] = new byte[ 15 ];
file.readFully( b2 );
lastName = new String( b2 );
lastName=lastName.trim();
balance = file.readDouble();
}
Defining a class to be
used for reading and
writing records to a
random access file
{
// Write a record to the specified RandomAccessFile
public void write( RandomAccessFile file ) throws IOException
{
file.writeInt( account );
byte b1[] = new byte[ 15 ];
if ( firstName != null )
b1 = firstName.getBytes();
file.write( b1 );
byte b2[] = new byte[ 15 ];
if ( lastName != null )
b2 = lastName.getBytes();
file.write( b2 );
file.writeDouble( balance );
}
public int getAccount(){ return account;}
public String getlName(){ return lastName;}
public String getfName(){ return firstName;}
public double getBalance(){ return balance;}
// NOTE: This method contains a hard coded value for the size of a
// record of information.
public int size() { return 42; }
}
import java.io.*;
public class CreateRandFile {
private Record blank;
RandomAccessFile file;
public CreateRandFile()
{
blank = new Record();
try {
file = new RandomAccessFile( "credit.dat", "rw" );
}
catch( IOException e ) {
System.err.println( "File not opened properly\n" +
e.toString() );
System.exit( 1 );
}
}
public void create()
{
try {
for ( int i = 0; i < 100; i++ )
blank.write( file );
}
catch ( IOException e ) {
System.err.println( e.toString() );
}
}
public static void main( String args[] )
{
CreateRandFile accounts = new CreateRandFile();
accounts.create();
}
}
This program creates
a random access file
sequentially by
writing 100 empty
records to disk.
RandomAccessFile
Methods to read
– write(byte[])
– writeInt(int)
– writeDouble(double)
Method to write
– int readInt();
– readFully(byte[]);
– Double readDouble();
# of bytes:
short 2; char 2; int 4; long 8; float 4; double 8;
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class WriteRandFile extends JFrame {
// Application window components
JTextField acct,
// where user enters account number
fName,
// where user enters first name
lName,
// where user enters last name
bal;
// where user enters balance
JButton enter,
// send record to file
done;
// quit program
JLabel acctLabel,
// account label
fNameLabel,
// first name label
lNameLabel,
// last name label
balLabel;
// balance label
RandomAccessFile output;
Record data;
// file for output
public WriteRandFile()
{
super( "Write to random access file" );
data = new Record();
try {
output = new RandomAccessFile( "credit.dat", "rw" );
}
catch ( IOException e ) {
System.err.println( e.toString() );
System.exit( 1 );
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
Container c = getContentPane();
c.setLayout( new GridLayout( 5, 2 ) );
acct = new JTextField( 20 );
acctLabel = new JLabel( "Account Number" );
fName = new JTextField( 20 );
fNameLabel = new JLabel( "First Name" );
lName = new JTextField( 20 );
lNameLabel = new JLabel( "Last Name" );
bal = new JTextField( 20 );
balLabel = new JLabel( "Balance" );
enter = new JButton( "Enter" );
done = new JButton( "Done" );
c.add( acctLabel );
// add label
c.add( acct );
// add TextField
c.add( fNameLabel ); // add label
c.add( fName );
// add TextField
c.add( lNameLabel ); // add label
c.add( lName );
// add TextField
c.add( balLabel );
// add label
c.add( bal );
// add TextField
c.add( enter );
// add button
c.add( done );
// add button
done.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
cleanup(); // write data, close file, etc.
setVisible(false);
dispose(); // release system resources
System.exit( 0 );
} }
);
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
enter.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
addRecord();
} }
);
setSize( 300, 150 );
setVisible( true );
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
public void addRecord()
{
int acctNum = 0;
Double d;
acctNum = ( new Integer( acct.getText() ) ).intValue();
// output the values to the file
try {
if ( acctNum > 0 && acctNum <= 100 ) {
String f=fName.getText();
String l=lName.getText();
double b=Double.parseDouble(bal.getText());
data = new Record(acctNum,f,l,b);
output.seek( (long) ( acctNum-1 ) * data.size() );
data.write( output );
// clear the TextFields
acct.setText( "" );
fName.setText( "" );
lName.setText( "" );
bal.setText( "" );
}
else {
acct.setText( "Enter valid account (1-100)" );
acct.selectAll();
}
}
catch ( IOException e ) {
System.err.println( "Error during write to file\n" +
e.toString() );
System.exit( 1 );
}
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
seek method of
RandomAccessFile:
sets file-position
pointer to a specific
point in file
public void cleanup()
{
if ( !acct.getText().equals("") )
addRecord();
try {
output.close();
}
catch ( IOException e ) {
System.err.println( "File not closed properly\n" +
e.toString() );
System.exit( 1 );
}
}
public static void main( String args[] )
{
WriteRandFile accounts = new WriteRandFile();
}
}
This program uses
TextFields to get
information from the
user at the keyboard
and writes the
information to a
random access file.
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ReadRandFile extends JFrame {
// Application window components
JTextField acct,
// where user enters account number
fName,
// where user enters first name
lName,
// where user enters last name
bal;
// where user enters balance
JButton next,
// send record to file
done;
// quit program
JLabel acctLabel,
// account label
fNameLabel,
// first name label
lNameLabel,
// last name label
balLabel;
// balance label
RandomAccessFile input; // file for output
Record data;
boolean moreRecords=true;
public ReadRandFile()
{
super( "Write to random access file" );
data = new Record();
try {
input = new RandomAccessFile( "credit.dat", "r" );
}
catch ( IOException e ) {
System.err.println( e.toString() );
System.exit( 1 );
}
This program opens a
random-access file
and displays only the
records with data.
Container c = getContentPane();
c.setLayout( new GridLayout( 5, 2 ) );
acct = new JTextField( 20 );
acctLabel = new JLabel( "Account Number" );
fName = new JTextField( 20 );
fNameLabel = new JLabel( "First Name" );
lName = new JTextField( 20 );
lNameLabel = new JLabel( "Last Name" );
bal = new JTextField( 20 );
balLabel = new JLabel( "Balance" );
next = new JButton( "Next" );
done = new JButton( "Done" );
c.add( acctLabel );
// add label
c.add( acct );
// add TextField
c.add( fNameLabel ); // add label
c.add( fName );
// add TextField
c.add( lNameLabel ); // add label
c.add( lName );
// add TextField
c.add( balLabel );
// add label
c.add( bal );
// add TextField
c.add( next );
// add button
c.add( done );
// add button
This program opens a
random-access file
and displays only the
records with data.
done.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
cleanup(); // write data, close file, etc.
setVisible(false)();
dispose(); // release system resources
System.exit( 0 );
} }
);
next.addActionListener(
new ActionListener () {
public void actionPerformed( ActionEvent event ){
readRecord();
} }
);
setSize( 300, 150 );
setVisible( true );
}
This program opens a
random-access file
and displays only the
records with data.
public void readRecord()
{
try {
do { // loop over empty records
data.read( input );
} while ( input.getFilePointer() < input.length() &&
data.getAccount() == 0 );
}
catch( IOException e ) {
moreRecords = false;
}
// transfer full record data into textfields
if ( data.getAccount() != 0 ) {
acct.setText( String.valueOf( data.getAccount() ) );
String fN=data.getfName();
fName.setText( fN);
String lN=data.getlName();
lName.setText( lN );
bal.setText( String.valueOf( data.getBalance() ) );
}
}
This program opens a
random-access file
and displays only the
records with data.
public void cleanup()
{
try {
input.close();
}
catch ( IOException e ) {
System.err.println( e.toString() );
System.exit( 1 );
}
}
public static void main( String args[] )
{
ReadRandFile accounts = new ReadRandFile();
}
}
This program opens a
random-access file
and displays only the
records with data.
Application: Transaction Processing
• Substantial transaction-processing system
– Uses random-access file
– Updates, adds and deletes accounts