What We Will Cover
Continuations
Homework Questions?
^ top
11.1: Files and File Objects
Objectives
At the end of the lesson the student will be able to:
- Describe the two common classifications of files
- Create and use
File objects
- Get information about files from the file system
- List directory contents
|
^ top
11.1.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
11.1.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 OS keeps track of the number of bytes in a file
- Using either an end-of-file marker or counting the number of bytes
- Files must have a name
- Naming requirements depend on the underlying operating system (OS)
- The OS organizes files into directories
^ top
11.1.3: Types of Files
- All data and programs are ultimately just zeros and ones
- Each binary digit can have one of two values: 0 or 1
- A bit is one binary digit
- A byte is a group of eight bits
- Programs group files into two broad categories: text and binary
Text Files
- In text files, the bits represent printable characters
- Source code is stored as a text file
- Files are usually stored as one byte per character (ASCII)
- Since Java supports Unicode, some characters need two or three bytes
- Each record (like a line) are often delimited by end-of-line characters
- Macintosh (before OS-X): "
\r"
- Unix: "
\n"
- Windows: "
\r\n"
- Individual fields within a record are often delimited by commas, tabs or other special characters
- You can read text files because each byte is translated by display devices into readable characters
Binary Files
- Everything other than text is called binary
- Each bit represents some type of encoded information
- E.g.: program instructions or numeric data
- Binary files are easily read by the computer but not by humans
For Example
- If we wanted to store an
int value of 1234 in a file
- We know an
int is four bytes long
- We can store our value as either
1234 or "1234"
- How we store it determines what is actually written to the file
| Description |
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
(int) 1234 as binary bits |
00000000 |
00000000 |
00000100 |
11010010 |
(int) 1234 as bytes |
0 |
0 |
4 |
210 |
"1234" as char's |
'1' |
'2' |
'3' |
'4' |
| "1234" as ASCII codes |
49 |
50 |
51 |
52 |
^ top
11.1.4: Creating File Objects
- Java uses a File class to perform basic operations on a file or directory
- You create a
File object referring to a file
- Then you use methods of the
File object to query the system for information about the 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 = "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
11.1.5: Methods of the File Class
- You can use a
File object for many tasks
- The first group of methods test a file or directory
- For instance: is a file readable or writeable
- The second group returns information about a file
- For instance: getting a name or the data last modified
- The third group works with directories
- For instance: list directory contents or make directories
- The fourth group contains some important methods like creating or deleting files
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 path 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
11.1.6: Examples Using Files and Directories
- In this section, we show examples using the File object
- The first example shows how to get information about a file
- The second example shows how to work with a directory and list its contents
Getting Information About a File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import java.io.*;
public class FileInfo {
public static void main(String[] args)
throws IOException {
File testFile = new File("testfile.txt");
testFile.createNewFile();
if (testFile.exists()) {
System.out.println("Name: "
+ testFile.getName());
System.out.println("Path: "
+ testFile.getPath());
System.out.println("Writable: "
+ testFile.canWrite());
} else
System.out.println(testFile.getName()
+ " does not exist.");
}
}
|
Listing Directory Contents
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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]);
}
}
}
}
|
^ top
11.1.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
Check Yourself
- What is a file?
- What are the two common classifications of files?
- What class is used to work with files?
^ top
Exercise 11.1
In this exercise, we explore use of a File object.
Specifications
- Save the following code file as
FileInfo.java.
- Add code to the program that displays the following information:
- Length of the file
- Time the files was last modified
Note: to display the timestamp in a more readable format, use the following code:
import java.util.Date;
...
Date ts = new Date(timestamp);
System.out.println(ts);
- Submit your modified
FileInfo program as the answer for this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import java.io.*;
public class FileInfo {
public static void main(String[] args)
throws IOException {
File testFile = new File("testfile.txt");
testFile.createNewFile();
if (testFile.exists()) {
System.out.println("Name: "
+ testFile.getName());
System.out.println("Path: "
+ testFile.getPath());
System.out.println("Writable: "
+ testFile.canWrite());
} else
System.out.println(testFile.getName()
+ " does not exist.");
}
}
|
^ top
11.2: Streams and File I/O
Objectives
At the end of the lesson the student will be able to:
- Describe the purpose of a stream
- Write text to files
- Read text from files
- Describe the procedure for file I/O
|
^ top
11.2.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 a file
- 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
- You use character streams to read and write text files
- FileReader: a stream for reading characters from a file
- FileWriter: a stream for writing characters to a file
- You use binary streams to read and write binary files
- We will use character streams to learn about file I/O because we can see the file contents in a text editor
^ top
11.2.2: Layering Streams
- Usually, any one stream does have not all the functionality you want
- Instead, it is common to layer two or more streams
For Example
- To write to a text file, we use a FileWriter object
FileWriter fw = new FileWriter("outfile.txt");
However, a FileWriter does not know how to write different types of data
That's why we combine the FileWriter with a PrintWriter
PrintWriter out = new PrintWriter(fw);
Now we can use the overloaded print() and println() methods of a PrintWriter object to write various data types
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:
File outfile = new File("outfile.txt");
FileWriter fw = new FileWriter(outfile);
BufferedWriter buf = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(buf);
Another way to write the same functionality:
File outfile = new File("outfile.txt");
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(outfile)));
Note that the File object is not part of the reformatting
You need a reference variable for the File object to access it methods
^ top
11.2.3: Example of File I/O
- As an example, let us write an application that reads and writes files
- We read a file named
infile.txt, which contains the following 3 values:
10
20
30
We sum the numbers and write the sum to a second file named outfile.txt
What do you notice that is familiar and what is new about the following code?
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
|
import java.io.*;
import java.util.Scanner;
class Sum3App {
public static void main(String[] args)
throws IOException {
File infile = new File("infile.txt");
File outfile = new File("outfile.txt");
// Open the streams
Scanner in = new Scanner(
new BufferedReader(
new FileReader(infile)));
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(outfile)));
// Read the data
double num1 = in.nextDouble();
double num2 = in.nextDouble();
double num3 = in.nextDouble();
// Perform the computation
double total = num1 + num2 + num3;
// Output the results
out.println("The sum of the first 3 numbers");
out.println("in infile.txt is: " + total);
// Close the streams
in.close();
out.close();
System.out.println("Processing completed");
}
}
|
- How does the program get its input?
- Where does the program send its output?
^ top
11.2.4: Procedure for File I/O
- Import the Java I/O library and, if you are reading data, the
Scanner library.
import java.io.*;
import java.util.Scanner;
- Create
File objects and open streams as needed for I/O.
File infile = new File("infile.txt");
Scanner in = new Scanner(
new BufferedReader(
new FileReader(infile)));
File outfile = new File("outfile.txt");
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(outfile)));
- Read data using a
Scanner object and write data using print() or println().
// Read the data
double num1 = in.nextDouble();
// Output data
out.println("The sum of the first 3 numbers");
out.println("in infile.txt is: " + total);
- Close the streams when finished to free up computer resources.
in.close();
out.close();
^ top
11.2.5: Summary
- Programs can 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 character 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
- The procedure for File I/O has four steps as shown above.
Check Yourself
- What is used to connect a program to a file or
File object?
- What library is required for file I/O?
- How are streams declared?
- Why do you layer streams?
- What streams do you typically use for reading?
- What streams do you typically use for writing?
- After opening a stream for reading, how do you read the data?
- After opening a stream for writing, how do you write data?
- Why should you close a stream after you are done using it in your program?
^ top
Exercise 11.2
In this exercise we write a program that copies one line of text from an input stream to an output stream.
Specifications
- Save the following code as
CopyOneApp.java.
- Save the file infile.txt to the same directory as your program source code.
- Declare and open an input stream named in that reads from a file named
infile.txt.
- Declare and open an output stream named out that writes to a file named
outfile.txt.
- Add code to read the first number from the input stream and save it to the output stream.
- Add code to close both of the streams.
- Compile and run your program.
- View the
outfile.txt file using a test editor to verify that one number was copied.
- Submit your program as the answer to this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import java.io.*;
import java.util.Scanner;
class CopyOneApp {
public static void main(String[] args)
throws IOException {
File infile = new File("infile.txt");
File outfile = new File("outfile.txt");
// Open the streams
// Read the data
// Output the results
// Close the streams
System.out.println("Processing completed");
}
}
|
^ top
11.3: More I/O Topics
Objectives
At the end of the lesson the student will be able to:
- Append data to an existing file
- Use a loop to read all the data in a file
- Handle file I/O exceptions
|
^ top
11.3.1: Alternate Syntax for Opening a Stream
- It is possible to create a stream without using a
File object
- Instead, you can specify the file name as an argument to
FileReader or FileWriter
- For example:
Scanner in = new Scanner(
new BufferedReader(
new FileReader("infile.txt")));
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter("outfile.txt")));
However, when using this technique you can no longer use the methods of the File class
^ top
11.3.2: Appending to a File
- The standard open operation for writing begins with an empty file
- Even if the file exists you loose all the contents
- To prevent loosing the information, you must open for appending to the file
File outfile = new File("outfile.txt");
FileWriter fw = new FileWriter(outfile);
If the file doesn't exist then FileWriter creates it
If the file exists then FileWriter positions itself to append to the end
The second argument is a boolean value where true means append
For Example
- The following program will add a message to the file every time we run it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import java.io.*;
import java.util.Scanner;
class AppendMessageApp {
public static void main(String[] args)
throws IOException {
Scanner input = new Scanner(System.in);
System.out.print("Enter a message to write: ");
String message = input.nextLine();
File outfile = new File("outfile.txt");
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter(outfile, true)));
out.println(message);
out.close();
System.out.println("Finished writing message");
}
}
|
^ top
11.3.3: Using Loops to Read a 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 test when your program reaches the end of a file
Example Using a Loop to Read a File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import java.io.*;
import java.util.Scanner;
class TextFileReader {
public static void main(String[] args)
throws IOException {
File data = new File("TextFileReader.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
11.3.4: Handling I/O Exceptions
- File I/O requires you to work with I/O exceptions
- To handle I/O exceptions, you need to throw them or code
try-catch statements
- So far, we have been throwing the exceptions
- Instead of throwing the exceptions, we can handle them in the usual way
try {
// One or more statements at least one of which
// should be capable of throwing an exception
} catch (Exception e) {
// Exception handling code
// Can have many catch blocks
}
Shown below are two common exception classes you can work with
Note that since we use a Scanner for input, we can get other exceptions as well
The Scanner exceptions were covered in lesson 9.3: Exception Handling Basics
Two Common I/O Exceptions
Example Handling File Exceptions
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
|
import java.io.*;
import java.util.Scanner;
class TextFileReader2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("File name to read: ");
String fileName = input.nextLine();
showFile(fileName);
}
public static void showFile(String fileName) {
Scanner in = null;
try {
File data = new File(fileName);
in = new Scanner(
new BufferedReader(
new FileReader(data)));
while (in.hasNext()) {
String line = in.nextLine();
System.out.println(line);
}
in.close();
} catch(FileNotFoundException fnfe) {
System.out.println("No such file");
return;
} catch(IOException ioe) {
System.out.println("Got an IOException.");
in.close();
ioe.printStackTrace();
System.exit(1);
}
}
}
|
^ top
11.3.5: Avoiding a FileNotFoundException
- We can use a
File object to avoid a FileNotFoundException
- Avoiding exceptions is often preferable where easily done
- You should reserve exception handling for true errors
- Note that even if you avoid a
FileNotFoundException, you still need to handle the general IOException
- An
IOException is a catch-all for file I/O exceptions
- By avoiding or handling normal exceptions, we make sure that any
IOException that does occur is truly an exceptional problem
- The following shows how to use a
File object to avoid a FileNotFoundException
Example Avoiding a FileNotFoundException
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.io.*;
import java.util.Scanner;
class TextFileReader3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("File name to read: ");
String fileName = input.nextLine();
showFile(fileName);
}
public static void showFile(String fileName) {
Scanner in = null;
try {
File data = new File(fileName);
if (data.exists()) { // avoid FileNotFoundException
in = new Scanner(
new BufferedReader(
new FileReader(data)));
while (in.hasNext()) {
String line = in.nextLine();
System.out.println(line);
}
in.close();
}
} catch (IOException ioe) {
System.out.println("Got an IOException.");
in.close();
ioe.printStackTrace();
System.exit(1);
}
}
}
|
^ top
11.3.6: Summary
- The standard open operation for writing begins with an empty file
- Even if the file exists you loose all the contents
- To prevent loosing the information, you must open for appending to the file new
File outfile = new File("outfile.txt");
FileWriter fw = new FileWriter(outfile);
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 hasNextLine() to see if there is any more input of the correct type in the stream
You can use these methods to signal when your program reaches the end of a file
while (in.hasNextLine()) {
String line = in.nextLine();
System.out.println(line);
}
Many Java I/O classes throw I/O exceptions that you need to handle
You must either throw the exceptions or code try-catch statements
Some exceptions can be avoided, which is often preferable
Exceptions should be reserved for exceptional conditions and not the normal flow of your program
Check Yourself
- How do you keep a file that is opened for writing from destroying existing information?
- What looping structure do you use to read all the data in a file?
- What two exceptions do you often need to handle for file I/O?
- How do you avoid throwing a
FileNotFoundException
^ top
Exercise 11.3
In this exercise we explore reading all the lines of a file using a loop and handling I/O exceptions.
Specifications
- Save the following code file as
ShowFileApp.java.
- Using the
fileName entered by the user, add code that displays the file to the screen.
- Submit your completed program as the solution for this exercise.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import java.io.*;
import java.util.Scanner;
public class ShowFileApp {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("File name to read: ");
String fileName = input.nextLine();
// Add code to read and display a file here
}
}
|
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Schedule
| Expectations
| Course info
Help
| FAQ's
| HowTo's
| Links
Last Updated: November 06 2005 @22:30:09
|