What We Will Cover
Illuminations
Questions on Assignment?
^ top
9.1: Exception Handling Basics
Learner Outcomes
At the end of the lesson the student will be able to:
- Describe the Java syntax for exception handling
- Write code to catch and handle exceptions
- Generate code to handle user-input errors
|
^ top
9.1.1: About Exceptions
- A common way to develop a program is to first make the code work assuming that nothing unusual happens
- After the usual case works, then you start to consider the exceptional cases like:
- What if a users enter letters when you want numbers
- What if a file your program needs was moved or deleted
- Java helps you to write your code in just this way:
- You first write your code as if nothing unusual will happen
- When the usual case works correctly, you add code to handle exceptional cases
- The mechanism to handle the unusual cases is known as exception handling
- Exception handling is an important part of developing "solid" or "robust" programs
- A solid or robust program means that you can run the program day after day
- If crazy or unusual things happen, the program copes or at least recognizes that something is wrong
Terminology
- Exception: an error condition that changes the normal flow of a program
- Throw an exception: either the Java runtime or your code signals that something unusual happened
- Catch an exception: take appropriate action to deal with an exception
- Exception handler: the code that processes an exception
Example Program the Causes an Exception
1
2
3
4
5
6
|
public class ExceptionDemo {
public static void main(String[] args) {
String str = null;
System.out.println(str.length());
}
}
|
How Exceptions Work
^ top
9.1.2: Exception Example
- Many exceptions can occur because of user input errors
- As an example, let us look at how you might handle user input errors
- Following is a simple program showing the usual case
The Usual Case
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import java.util.*;
public class TotalCalculator1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
System.out.print("Enter cost: ");
cost = input.nextDouble();
System.out.print("Enter tax: ");
tax = input.nextDouble();
double total = cost + tax;
System.out.println("Total: " + total);
System.out.println("Thanks for paying!");
}
}
|
- The program works for the usual case but can fail on invalid data
- What happens if the user enters a dollar sign before the numbers?
- What happens if the user enters letters instead of numbers?
- What if the user enters Ctrl-C
Enter cost: $100
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextDouble(Scanner.java:2387)
at TotalCalculator1.main(TotalCalculator1.java:9)
- The program prints the message shown above and then ends
- This is not desirable behavior, so we need to catch and handle the exception
- In Java, you catch and handle exceptions with a
try-catch statement
^ top
9.1.3: Handling Exceptions
Example of Exception Handling
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.util.*;
public class TotalCalculator2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
try {
System.out.print("Enter cost: ");
cost = input.nextDouble();
System.out.print("Enter tax: ");
tax = input.nextDouble();
double total = cost + tax;
System.out.println("Total: " + total);
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
} catch(NoSuchElementException e) { // Ctrl-C
System.out.println("\nGoodbye!");
System.exit(0);
}
System.out.println("Thanks for paying!");
}
}
|
^ top
9.1.4: Exception Flow of Control
- When an exception occurs:
- The method stops processing at the point of failure
- The code creates an object with the error information
- The JVM tries to locate the exception handling code
- If the JVM finds the exception-handling code, the matching
catch block is passed the exception object
- If the JVM does not find a matching catch block, it uses the general exception handler instead
- General exception handler displays an error messages on the console like the following and then ends the program
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextDouble(Scanner.java:2335)
at ReceiptCalculator.main(ReceiptCalculator.java:9)
- Let us trace through the flow for our example code
- The user enters bad data and the
main() method stops processing
Enter cost: $100
- The scanner object code creates an exception object of type
InputMismatchException
- the JVM passes the exception object to the
catch statement:
catch(InputMismatchException e)
- The exception handling code executes
- The program continues with the code after the list of
catch blocks
- Note that the program does not execute the second input statement
- As soon as the error occurs, the program jumps to the exception handler
- Program execution continues after the exception handler code
^ top
9.1.5: Trying Again
- To allow the user to try again when there is an error, we need to code a loop
- One way is to use a looping statement like the following
Example of Verification Using a Loop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import java.util.*;
public class TotalCalculator3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
boolean more = true;
while (more) {
try {
System.out.print("Enter cost: ");
cost = input.nextDouble();
System.out.print("Enter tax: ");
tax = input.nextDouble();
double total = cost + tax;
System.out.println("Total: " + total);
more = false;
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
input.nextLine(); // clear the buffer
} catch(NoSuchElementException e) {
System.out.println("\nGoodbye!");
System.exit(0);
}
}
System.out.println("Thanks for paying!");
}
}
|
^ top
9.1.6: Verifying in Methods
Example of Verification Using a Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import java.util.*;
public class TotalCalculator4 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
cost = readDouble(input, "Enter cost: ");
tax = readDouble(input, "Enter tax: ");
double total = cost + tax;
System.out.println("Total: " + total);
System.out.println("Thanks for shopping!");
}
/**
* Read a double from the console.
*
* @param input Scanner object to read from.
* @param prompt User prompt to show before input
* @return A double entered by the user.
*/
public static double readDouble(Scanner input,
String prompt) {
double number = 0;
boolean more = true;
while (more) {
try {
System.out.print(prompt);
number = input.nextDouble();
more = false;
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
input.nextLine(); // clear the buffer
} catch(NoSuchElementException e) {
System.out.println("\nGoodbye");
System.exit(0);
}
}
return number;
}
}
|
- Note that there is still a loop in the
readDouble() method -- can you see it?
- Programmers commonly develop a library of static input methods like these
^ top
9.1.7: Summary
- A common way to develop a program is to first make the code work assuming that nothing unusual happens
- After the usual case works, then you consider the exceptional cases
- Java provides exception handling to handle these exceptional cases
- Many exceptions can occur because of user input errors
- To catch and handle exceptions you use both
try and catch statements
try {
// One or more statements that can throw an exception
} catch(Exception e) {
// Exception handling code
// Can have many catch blocks
}
- To allow users to correct their errors, you need to add a looping mechanism around the input statement
boolean more = true;
while (more) {
try {
System.out.print("Enter net cost: ");
cost = input.nextDouble();
// May have more statements
more = false;
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
input.nextLine(); // clear the '\n'
} // may need more catch statements
}
- Since input is a frequent occurrence, it is common to write user input methods
- One example is
readDouble():
public static double readDouble(Scanner input,
String prompt) {
double number = 0;
boolean more = true;
while (more) {
try {
System.out.print(prompt);
number = input.nextDouble();
more = false;
} catch(InputMismatchException e) {
System.out.println(
"Error -- only enter numbers!");
input.nextLine(); // clear the input
} catch(NoSuchElementException e) {
System.out.println("\nGoodbye");
System.exit(0);
}
}
return number;
}
Check Yourself
- What is an exception?
- What is an exception handler?
- What is a stack trace?
- What is the Java syntax for exception handling
- When is the code within a catch block executed?
^ top
Exercise 9.1
Take one minute to prepare an answer the following question.
- By number, which lines are executed by the following if the user enters "$100" for the cost?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.util.*;
public class TotalCalculator2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
try {
System.out.print("Enter cost: ");
cost = input.nextDouble();
System.out.print("Enter tax: ");
tax = input.nextDouble();
double total = cost + tax;
System.out.println("Total: " + total);
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
} catch(NoSuchElementException e) { // Ctrl-C
System.out.println("\nGoodbye!");
System.exit(0);
}
System.out.println("Thanks for paying!");
}
}
|
^ top
9.2: More Exception Topics
Learner Outcomes
At the end of the lesson the student will be able to:
- Explain the difference between checked and unchecked exceptions
- Use the
throws clause when defining a method
- Throw an exception
- Use predefined
Exception classes
- Write a custom class that defines a new exception
|
^ top
9.2.1: Kinds of Exceptions
- Java has three categories of exceptional conditions:
- Errors
- Checked exceptions
- Unchecked exceptions
- These exceptions are organized in an inheritance hierarchy as shown below

- Exceptions with
RuntimeException as an ancestor are unchecked exceptions
Errors
- Errors are exceptional conditions that are external to the application
- Usually the application cannot recover from these types of errors
- For example, suppose that while your program is reading from a file that the computer has a hardware failure
- You may want to alert the user, but there is little that the program can do to recover
Checked Exceptions
- A checked exception is an exceptional condition that a program should be able to recover from
- Java forces these types of problems to be provided for if they occur
- The compiler checks that some mechanism is in place for receiving and processing the exception object
- Since it is checked by the compiler, it is known as a checked exception
- An example of this type of exception is the
FileNotFoundException
- Normally, your program reads a file using a name supplied by the user
- However, sometimes a user will supply a wrong name
- In these cases your program should notify the user and ask for the correct name
Unchecked (Runtime) Exceptions
^ top
9.2.2: What Exception Can Occur?
Enter cost: $100
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextDouble(Scanner.java:2387)
at TotalCalculator1.main(TotalCalculator1.java:9)
- This tells you that you need to code a
try-catch for an InputMismatchException
- Sometimes you might want to know what the possible exceptions might be in your code
- To find out, you can look up exceptions in the Java API
- For example, you can look up the documentation for the
Scanner method: nextDouble()
- You then examine the list of possible exceptions and determine if and how they might occur in your program
- Note that exceptions with
RuntimeException as an ancestor are unchecked
- Otherwise, they are checked exceptions
More Information
^ top
9.2.3: Using the throws Clause
- Anytime your program uses a method that can cause a checked exception, your program must do something with it
- If you decide the method cannot handle the exception, you use a
throws clause to send the exception to the caller
- The general syntax for throwing an exception:
[accessModifier] returnType methodName(parameterList)
throws ExceptionType1, ExceptionType2,... {
// statements
}
- Where:
- accessModifier: determines which classes can access this method
- returnType: the type of value returned by the method, or
void for no return value
- methodName: the name you make up for the method
- parameterList: the types and names of the parameters
- ExceptionTypeX: the type of exception a method throws
- For example:
public static void main(String[] args)
throws java.io.IOException {
- Throwing an exception is like passing the buck:
- Requires the calling method to deal with the exception
- The calling method can also throw the exception
- Eventually some method should catch it or the general exception handler is called
How Exceptions are Propagated
- When methods cannot handle an exception, that method should throw the exception
- The user of the method can then decide how to handle the exception
- Methods can call other methods that can throw an exception
- This chain continues usually until one method catches the exception

Example of Exception Propagation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class ExceptionPropogation {
public static void main(String[] args) {
methodD();
}
public static void methodD() {
try {
methodC();
} catch (Exception e) {
System.out.println("Caught exception");
}
}
public static void methodC() throws Exception {
methodB();
}
public static void methodB() throws Exception {
methodA();
}
public static void methodA() throws Exception {
throw new Exception();
}
}
|
^ top
9.2.4: Throwing Exceptions
- You may be wondering how the code in
Scanner and other classes generates an exception
- The answer is the Java
throw statement
- Syntax:
throw new ThrowableObject
- Where:
- ThrowableObject: the exception class to throw
- For example:
throw new Exception("Exception message");
- Typically, you decide to throw an exception after checking for an error condition:
if (cost < 0) {
throw new Exception(
"Cost cannot be less than 0");
}
- To demonstrate, let us throw an exception in an example program
Example Program Using throw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import java.util.*;
public class TotalCalculator5 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double cost = 0, tax = 0;
boolean more = true;
while (more) {
try {
System.out.print("Enter cost: ");
cost = input.nextDouble();
if (cost < 0) {
throw new Exception(
"Cost cannot be less than 0");
}
System.out.print("Enter tax: ");
tax = input.nextDouble();
if (tax < 0) {
throw new Exception(
"Tax cannot be less than 0");
}
double total = cost + tax;
System.out.println("Total: " + total);
more = false;
} catch(Exception e) {
String message = e.getMessage();
System.out.println(message);
input.nextLine(); // clear the buffer
}
}
System.out.println("Thanks for paying!");
}
}
|
- Note the use the
getMessage() method to explain the error
- There are a few other commonly used exception methods shown in the table below
When to Throw an Exception
- Your program should only throw exceptions for exceptional conditions
- This may happen when a method encounters a situation where it cannot complete its task
- For example: the wrong file name was passed to the method opening a file
- Throw an exception to the calling method, which can ask the user for the correct name
Commonly Used Methods of the Throwable Class
| Method |
Description |
| getMessage() |
Returns the message associated with the exception, if available. |
| printStackTrace() |
Prints the stack trace to the standard error stream. |
| toString() |
Returns a string with the name of the exception class along with the message associated with the exception, if available. |
^ top
9.2.5: Predefined Exception Classes
- As we have seen, there are more exception classes than the single class
Exception
- Some of them are shown in the following tree
- You can also write your own exceptions, which we will cover in the following section
- However, you should use standard exceptions wherever possible
java.lang.Throwable
|
+--java.lang.Error (Unchecked)
|
+--java.lang.Exception (Checked)
|
+--java.lang.InterruptedException
|
+--java.io.IOException
|
+--java.lang.RuntimeException (Unchecked)
|
+--java.lang.ArithmeticException
|
+--java.lang.IllegalArgumentException
|
+--java.lang.IllegalStateException
|
+--java.lang.IndexOutOfBoundsException
|
+--java.lang.NullPointerException
|
+--java.lang.UnsupportedOperationException
|
+--java.util.InputMismatchException
^ top
9.2.6: Writing Custom Exception Classes
- You can define your own exception class
- There are two main reasons to write your own exception class:
- To carry the precise information you want thrown to the catch block
- To have a different type for every kind of exceptional case
- You must derived your exception from some already defined exception class
- Often all you need to code is the constructors
- You should always define two constructors for an exception class:
- A constructor taking no arguments that defines a default message string and calls the superclass constructor
- A constructor that takes a
String message argument and calls the superclass constructor
- Following is a "toy" example of a custom exception class
Custom Exception Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class DivisionByZeroException extends Exception {
/**
* Default constructor with a default error message.
*/
public DivisionByZeroException() {
super("Division by zero!");
}
/**
* Overloaded constructor for custom error message.
*
* @param message The custom error message.
*/
public DivisionByZeroException(String message) {
super(message);
}
}
|
Program Using the Custom Exception
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
52
53
|
import java.util.*;
public class Divide2Nums {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double numerator = 0, denominator = 0;
double quotient = 0;
boolean valid = false;
numerator = readDouble(input,
"Enter numerator: ");
while (!valid) {
try {
denominator = readDouble(input,
"Enter denominator: ");
if (denominator == 0) {
throw new DivisionByZeroException();
}
quotient = numerator / denominator;
valid = true;
} catch (DivisionByZeroException e) {
System.out.println(e.getMessage());
}
}
System.out.println(numerator + " / "
+ denominator + " = " + quotient);
}
/**
* Read a double from the console.
*
* @param input Scanner object to read from.
* @param prompt User prompt to show before input
* @return A double entered by the user.
*/
public static double readDouble(Scanner input,
String prompt) {
double number = 0;
try {
System.out.print(prompt);
number = input.nextDouble();
} catch(InputMismatchException e) {
System.out.println(
"Error -- enter digits only!");
input.nextLine(); // clear the '\n'
return readDouble(input, prompt);
} catch(NoSuchElementException e) {
System.out.println("\nGoodbye!");
System.exit(0);
}
return number;
}
}
|
^ top
9.2.7: Summary
- Java has three categories of exceptional conditions:
- Errors: external to the application
- Checked exceptions: recoverable condition that the compiler forces a program to handle
- Unchecked exceptions: compiler does NOT force a program to handle
- These exceptions are organized in an inheritance hierarchy as shown below

Exception is the ancestor of checked exceptions and RuntimeException is the ancestor of unchecked exceptions
- To determine what kind of exception can occur, you can:
- Try the code and see what happens
- Look up the exceptions in the Java API
- If a method cannot handle the exception, it should throw the exception to the calling method
- To throw an exception you add a throws clause in the method header
public static void main(String[] args)
throws java.io.IOException {
- To create an exception condition, you code a
throw statement:
throw new Exception("Exception message");
- Typically, you decide to throw an exception after checking for an error condition, like:
if (cost < 0) {
throw new Exception(
"Cost cannot be less than 0");
}
- When you catch an exception, you can use
getMessage() to display the error message associated with the exception
- When throwing an exception, you can use a predefine exception class or write a custom exception class
- You should use predefined exception class whenever you can
- However, there are two main reasons to write your own exception class:
- To carry the precise information you want thrown to the catch block
- To have a different type for every kind of exceptional case
- You must derived your exception from some already defined
Exception class
- When writing your own exception, you should always define two constructors:
- A constructor taking no arguments that defines a default message string and calls the superclass constructor
- A constructor that takes a
String message argument and calls the superclass constructor
- For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class DivisionByZeroException extends Exception {
/**
* Default constructor with a default error message.
*/
public DivisionByZeroException() {
super("Division by zero!");
}
/**
* Overloaded constructor for custom error message.
*
* @param message The custom error message.
*/
public DivisionByZeroException(String message) {
super(message);
}
}
|
^ top
Exercise 9.2
Take one minute to prepare answers to the following questions:
- What output is produced by the following code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class WaitTime {
public static void main(String[] args) {
int waitTime = 50;
System.out.println("Before try-block");
try {
System.out.println("Entering try-block");
if (waitTime > 30) {
throw new Exception("Over 30");
} else if (waitTime < 30) {
throw new Exception("Under 30");
}
System.out.println("No exception");
System.out.println("Exiting try-block");
} catch(Exception e) {
System.err.println(e.getMessage());
}
System.out.println("After catch-block");
}
}
|
^ top
9.3: Streams and File I/O
Learner Outcomes
At the end of the lesson the student will be able to:
- List the types of files
- Create and use
File objects
- Get information about files from the native file system
- List directory contents
|
^ top
9.3.1: About Program I/O
- Program I/O = Program Input/Output
- Input to and output from programs
- Input can be from a keyboard, mouse or file
- Output can be to a display screen, printer or file
- Note that files can be both input and output devices for programs
- Advantages of file I/O:
- Data still exists after the program ends
- Input can be automated (rather than entered manually)
- Output from one program can be input to another
- To store and retrieve data in a file, we need two items:
- A file
- A file stream object
- We will look at files first
^ top
9.3.2: Files
File: a collection of data stored under a common name on a storage medium.
- Files provide long-term storage of large amounts of data
- Usually, you store files on non-volatile storage mediums
- Magnetic disks
- Optical disks
- Flash storage, like USB storage devices
- File are a single sequence of bytes
| Byte 0 |
Byte 1 |
Byte 2 |
... |
Byte n−1 |
End-of-file marker |
- The operating system keeps track of the number of bytes in a file
- Files must have a name
- Naming requirements depend on the underlying operating system (OS)
- The operating system organizes files into directories
^ top
9.3.3: Types of Files
- All data in a file is ultimately just zeros and ones
- It is up to the program using the file to understand the meaning and internal format of the data
- In general, programs interpret data using two broad categories: text and binary
Text Files
- In text files, the bits represent printable characters
- Files are usually stored as one byte per character (ASCII)
- Each line is delimited by end-of-line characters:
- Macintosh (before OS-X): "
\r"
- Unix: "
\n"
- Windows: "
\r\n"
- You can read text files because each byte is interpreted by a program as textual characters
- Some of these programs, like TextPad, then display the textual data to your computer's screen
- Since there are many programs that read and display text, text files are called human readable
Binary Files
- Data other than text is usually referred to as binary data
- Each bit represents some type of encoded information like program instructions or integer data
- Binary files are easily read by the computer but not by humans
- The following table compares binary and text values saved in a file
- First we consider the value "1234" as ASCII codes and compare these bits to a binary value of
1234
Comparing Binary and Textual Data
| Description |
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
"1234" as char's |
'1' |
'2' |
'3' |
'4' |
| "1234" as ASCII codes (bytes) |
49 |
50 |
51 |
52 |
| "1234" as ASCII codes (bits) |
00110001 |
00110010 |
00110011 |
00110100 |
(int) 1234 as binary bits |
00000000 |
00000000 |
00000100 |
11010010 |
^ top
9.3.4: Creating File Objects
- File class represents a file on the native file system
- You create a
File object referring to a file
- Then you can query the object for information about that file
Common Constructors for Class File
Examples of Creating Files Objects
- You can create a
File object in the current directory:
File myFile = new File("myfile.txt");
- Can create a
File object using an absolute pathname
- Specifies the entire path and file name for the file:
File myFile = new File("C:/docs/myfile.txt");
- You can use a relative pathname to specify a file
- Refers to a file starting from the current directory:
File myFile = new File("docs/myfile.txt");
- You can use a Universal Naming Convention to refer to a file
- Starts with two slashes (
//) followed by a hostname and pathname
File myFile = new File("//server/path/myfile.txt");
- You can use two strings to specify a file:
String pathname = "C:/docs";
String filename = "myfile.txt";
File myFile = new File(pathname, filename);
- You can use a
File object and a string to specify a file
File dir = new File("C:/docs");
File myFile = new File(dir, "myfile.txt");
- Note that forward slashes work on both UNIX and Windows systems
- Always use forward slashes to make your code more portable
^ top
9.3.5: Using File Objects
- We can use
File objects for many tasks
- For instance we can:
- Test some attributes of files or directories
- Get information about files
- Get lists of directory contents
- Create files and directories
- Delete files and directories
- You can see some of the commonly used methods listed below
Some Methods that Test a File
| Method |
Description |
| canRead() |
Returns true if the pathname exists and can be read by the program. |
| canWrite() |
Returns true if the pathname exists and a program can write to it. |
| exists() |
Returns true if the pathname exists. |
| isDirectory() |
Returns true if the pathname exists and refers to a directory. |
| isFile() |
Returns true if the pathname exists and refers to a file. |
Some Methods that Return Information about a File
| Method |
Description |
| getName() |
Returns the name of the file or directory as a String. |
| getPath() |
Returns the name of the file or directory as a String. |
| lastModified() |
Returns the time that the file was last modified as the number of milliseconds since January 1, 1970. |
| length() |
Returns the length of the file as a long type. |
Some Methods that work with Directories
| Method |
Description |
| list() |
If the object refers to a directory, returns an array of strings naming the files and directories. |
| listFiles() |
If the object refers to a directory, returns an array of File objects for the files and directories. |
| listRoots() |
A static method that returns an array of File objects representing the drives available to the current system. |
| mkdir() |
Creates the directory named by the File pathname. |
Other Methods that work with File Objects
| Method |
Description |
| createNewFile() |
Creates a new, empty file if a file with this name does not yet exist. |
| delete() |
Deletes the file or directory referred to by the File object. |
| setReadOnly() |
Makes the file read-only. If successful, returns true. |
^ top
9.3.6: Working with Files and Directories
- The following programs show some uses for the
File object
Getting Information About a File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import java.io.*;
public class FileInfo {
public static void main(String[] args) throws IOException {
File myFile = new File("myfile.txt");
myFile.createNewFile();
if (myFile.exists()) {
System.out.println("Name: " + myFile.getName());
System.out.println("Path: " + myFile.getPath());
System.out.println("Writable: " + myFile.canWrite());
} else
System.out.println("The " + myFile.getName()
+ " file doesn't exist.");
}
}
|
Listing Directory Contents
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import java.io.*;
public class DirList {
public static void main(String[] args)
throws IOException {
File dir = new File("./"); //current directory
if (dir.exists() && dir.isDirectory()) {
System.out.println("Dir: "
+ dir.getCanonicalPath());
String[] files = dir.list();
for (int i = 0; i < files.length; i++)
System.out.println(files[i]);
}
}
}
|
Working with I/O Exceptions
- Note the
throws IOException clause in the above examples
- File I/O requires you to work with I/O exceptions
- Your code will not compile unless you handle the exception
- Either using
try-catch or throws
- There are many types of I/O exceptions you can work with as shown below
- However,
IOException is the ancestor of all I/O exceptions
Common I/O Exceptions
^ top
9.3.7: Summary
- To identify a file you create a
File object
- You identify the file with either an absolute pathname or a relative pathname
- To identify a file on a remote computer, you use the Universal Naming Convention
- The
File class provides many methods that you can use to:
- Check whether a file or directory exists
- Get information about a file
- Create or delete files and directories
- Many methods of Java I/O classes throw I/O exceptions that you need to handle
Check Yourself
- What is the difference between a text file and a binary file?
- What is the purpose of the
File class?
- What is an absolute pathname?
- What is a relative pathname?
- What is an I/O exception?
- Why must you handle I/O exceptions?
- What can you do to handle I/O exceptions?
^ top
Exercise 9.3
Take one minute to prepare an answer to the Check Yourself questions. We will review the questions as time permits.
^ top
9.4: Text File I/O
Learner Outcomes
At the end of the lesson the student will be able to:
- Describe the purpose of a stream
- Work with I/O exceptions
- Write text to files
- Read text from files
|
^ top
9.4.1: Streams
Stream: a one-way transmission path that either delivers data to a destination (screen, file, etc.) or that takes data from a source (keyboard, file, etc.)
- A stream connects a program to an I/O object
- Input stream: an object that provides a sequence of bytes to a program

- Output stream: an object that accepts a sequence of bytes from a program

File Streams
File stream: a one-way transmission path used to connect a program to a file.
- File streams can be either input or output streams
- File input streams receive data from a file
- File output streams send data to a file
- Each file your program uses will need a separate file stream object
Basic File Streams
- Since there are two types of files, there are streams to support each type
- Use character streams to read and write text files:
- Use binary streams to read and write binary files:
^ top
9.4.2: Text Streams
- Streams are implemented using classes and objects
- To write and read text, you use character streams
- A character stream processes characters through the stream
- There is a separate set of classes for writing and reading character streams
- These classes are organized in an inheritance hierarchy as shown below
Some Classes from the Writer Hierarchy
Writer: Foundation class for writing character streams
|
+--BufferedWriter: Add a buffer to the stream
|
+--PrintWriter: Convert binary data to text
|
+--OutputStreamWriter: Bridge character to binary streams
|
+--FileWriter: Connects a stream to a file
Some Classes from the Reader Hierarchy
Reader: Foundation class for reading character streams
|
+--BufferedReader: Add a buffer to the stream
|
+--InputStreamReader: Bridge character to binary streams
|
+--FileReader: Connects a stream to a file
^ top
9.4.3: Layering Streams
- Usually, any one stream does have not all the functionality you want
- Instead, it is common to layer two or more streams
Writing to a Text Stream
Buffering
- Every time a byte or sequence of bytes is written or read to a file, the OS must perform a series of operations
- Buffering improves performance of I/O by reducing the number of calls to the OS
- A program copies each output to a block of memory called a buffer
- The entire buffer is output to disk at once
- One long disk access takes less time than many smaller ones

Adding a Buffered Layer
- You use buffered stream classes to improve I/O performance:
- We can add a buffering layer to our previous stream example:
FileWriter fw = new FileWriter("myfile.txt");
BufferedWriter buf = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(buf);
- Another way to write the same functionality:
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter("myfile.txt")));
^ top
9.4.4: Connecting a Character Output Stream to a File
- To write to a text file, you create a character output stream
- To do this, you need to layer two or more classes from the
Writer hierarchy
- An example of how to accomplish this task is shown below
Classes Connecting a Character Output Stream to a File
File data = new File("data.txt");
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(data)));
Mix and Match
^ top
9.4.5: Procedure for Writing a Text File
- Create a
File object with a pathname to your file:
File data = new File("data.txt");
- Connect the file to a stream with a
FileWriter:
FileWriter fw = new FileWriter(data);
If you want to append data then use:
FileWriter fw = new FileWriter(data, true);
- Add a buffer for the output with a
BufferedWriter:
BufferedWriter buf = new BufferedWriter(fw);
- Add methods to convert binary data to character data with a
PrintWriter:
PrintWriter out = new PrintWriter(buf);
- Write to the file using the
print() and println() methods:
out.println("This is a string");
out.println('c');
out.println(1234);
out.println(1.234);
for (int i = 0; i <= 10; i++) {
out.print(i + ",");
}
out.println();
- Close the streams when finished writing:
out.close();
Note that you can nest the constructor calls as shown in the example below
Example Program Writing a Text File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import java.io.*;
class TextWriterApp {
public static void main(String[] args)
throws IOException {
File data = new File("data.txt");
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(data)));
out.println("This is a string");
out.println('c');
out.println(1234);
out.println(1.234);
for (int i = 0; i <= 10; i++) {
out.print(i + " ");
}
out.println();
out.close();
System.out.println("Finished writing file");
}
}
|
^ top
9.4.6: Connecting a Character Input Stream to a File
- To read from a text file, you need to create a character input stream
- To do this, you need to layer two or more classes from the
Reader hierarchy
- Note that there is no "PrintReader" class
- Instead we can use the same
Scanner object we used for reading from the keyboard
- An example of how to accomplish this task is shown below
Classes Connecting a Character Output Stream to a File
File data = new File("data.txt");
Scanner in = new Scanner(
new BufferedReader(
new FileReader(data)));
Mix and Match
Some Commonly Used Methods of a Scanner Object
| Method |
Description |
next() |
Returns the next token as a String object. |
nextLine() |
Returns the rest of the current line as a String object. |
nextDouble() |
Provides classes to handle text, dates, and numbers |
nextInt() |
Returns the next token as an int value. |
^ top
9.4.7: Procedure For Reading a Text File
- Create a
File object with a pathname to your file:
File data = new File("data.txt");
- Connect the file to a stream with a
FileReader:
FileReader fr = new FileReader(data);
- Add a buffer for the input with a
BufferedReader:
BufferedReader bin = new BufferedReader(fr);
- Add a
Scanner object to parse the data:
Scanner in = new Scanner(bin);
- Read data using methods calls for the correct type:
int x = in.nextInt();
- Close the streams when finished reading:
in.close();
Note that you can nest the constructor calls as shown in the example below
Example Program Reading a Text File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import java.io.*;
import java.util.Scanner;
class TextReaderApp {
public static void main(String[] args)
throws IOException {
File data = new File("data.txt");
Scanner in = new Scanner(
new BufferedReader(
new FileReader(data)));
String str = in.nextLine();
System.out.println(str);
char ch = in.nextLine().charAt(0);
System.out.println(ch);
int x = in.nextInt();
System.out.println(x);
double d = in.nextDouble();
System.out.println(d);
for (int i = 0; i <= 10; i++) {
x = in.nextInt();
System.out.print(x + " ");
}
System.out.println();
in.close();
}
}
|
^ top
9.4.8: Testing for End of File
- Sometimes you do not know how many lines are in a file
- To solve this, the typical approach is to use a loop to process the file
- The
Scanner object has methods like hasNext() to see if there is any more input in the stream
- You can use these methods to signal when your program reaches the end of a file
Example Program Testing for End-of-File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import java.io.*;
import java.util.Scanner;
class TextReaderApp2 {
public static void main(String[] args)
throws IOException {
File data = new File("TextReaderApp2.java");
Scanner in = new Scanner(
new BufferedReader(
new FileReader(data)));
while (in.hasNext()) {
String line = in.nextLine();
System.out.println(line);
}
in.close();
}
}
|
Some Test Methods of a Scanner Object
| Method |
Description |
hasNext() |
Returns true if this scanner has another token in its input. |
hasNextLine() |
Returns true if there is another line in the input of this scanner. |
hasNextDouble() |
Returns true if the next token can be interpreted as a double value. |
hasNextInt() |
Returns true if the next token can be interpreted as an int value. |
^ top
9.4.9: Summary
- Programs read and write to files using streams
- A stream is a one-way transmission path that either delivers data to a destination or that takes data from a source.
- To read and write files, you use input and output streams
- Buffers improve the performance of disc operations by reducing the number of device operations
- To create a stream object with the desired functionality, you layer streams
Writing a Text File
Reading a Text File
Check Yourself
- How are I/O operations handled in Java?
- What is an output stream?
- What is an input stream?
^ top
Exercise 9.4
Take one minute to prepare an answer to the following question:
- What does the following snippet of code do?
File data = new File("data.txt");
Scanner in = new Scanner(
new BufferedReader(
new FileReader(data)));
int count = 0;
while (in.hasNextLine()) {
String line = in.nextLine();
count++;
System.out.println(count + ": " + line);
}
in.close();
^ top
Wrap Up
Due Next: A7-Alien Polymorphism (4/14/10)
A8-Image Manipulation (4/21/10)
^ top
Home
| Blackboard
| Schedule
| Room Policies
| Syllabus
Help
| FAQ's
| HowTo's
| Links
Last Updated: April 11 2010 @22:00:14
|