12: Files and Streams

What We Will Cover


Illuminations

Questions on Completed Assignments?

What to take next?

  • Fall 2005 Schedule of Classes
  • After completing CS-20J you are qualified to take:
    • CS-2: Foundations of Computer Science
    • CS-19: C++ programming and software design methodologies
    • CS-24: Elementary Computer Organization
  • CS-19 has an initial review section such that you could learn the syntax with a little effort
  • Other computer-related courses requiring programming:
    • CIS-165PH: Introduction to Programming Database-Driven Web Sites with PHP

12.1: Streams and File I/O

Objectives

At the end of the lesson the student will be able to:

  • List the types of files
  • Describe the purpose of a stream
  • Work with I/O exceptions

12.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, file or other input device
  • Output can be to a display screen, printer, file or other output device
  • 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

12.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

12.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
  • Files are usually stored as one byte per character (ASCII)
  • Each record (like a line) are often delimited by end-of-line characters
  • Individual fields within a record are often delimited by commas, tabs or other special characters
  • Source code is stored as a text file
  • 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
1234 as binary bits 00000000 00000000 00000100 11010010
1234 as bytes 0 0 4 210
"1234" as char's '1' '2' '3' '4'
"1234" as ASCII codes 49 50 51 52

12.1.4: 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

12.1.5: 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 text to a file, we use a FileWriter object
  • FileWriter fw = new FileWriter("out.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() 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:
  • 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")));
    

12.1.6: Working with I/O Exceptions

  • File I/O requires you to work with I/O exceptions
  • There are three common exception classes you work with shown below
  • To handle I/O exceptions, you need to throw them or code try-catch statements
  • Note that you can code your programs to avoid many of these exceptions

Common I/O Exceptions

Exception Description
IOException General purpose I/O exception.
EOFException Thrown when a program reads beyond the end of a file.
FileNotFoundException Thrown when a program tries to open a file that does not exist.

For Example

try {
    File data = new File("data.txt");
    if (data.exists()) { // avoid FileNotFoundException
        BufferedReader in = new BufferedReader(
                            new FileReader(data));
        String line = in.readLine();
        while (line != null) { // avoid EOFException
            System.out.println(line);
            line = in.readLine();
        }
        in.close();
    } else {
        System.out.println("File does not exist");
    }
} catch (IOException ioe) {
    System.out.println("An IOException has occurred.");
    System.exit(1);
}

12.1.7: 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 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
  • Many Java I/O classes throw I/O exceptions that you need to handle

Exercise 12.1

Take one minute to prepare an answer to the following questions:

  1. What is the difference between a text file and a binary file?
  2. How are I/O operations handled in Java?
  3. What is an output stream?
  4. What is an input stream?

12.2: File Class

Objectives

At the end of the lesson the student will be able to:

  • Create and use File objects
  • Get information about files from the native file system
  • List directory contents

12.2.1: Creating File Objects

  • File class represents a file on the native file system
  • You create a File object referring to a file
  • Then can query the object for information about that file

Common Constructors for Class File

Class Description
File(String pathname) Creates a File object that refers to the specified pathname.
File(String parent, String child) Creates a File object that refers to the pathname created by combining the parent and child pathnames.
File(File parent, String child) Creates a File object that refers to the pathname created by combining the pathname of parent with the child pathname.

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

12.2.2: Using File Objects

  • Can use File objects for many tasks
  • Can test some attributes of files or directories
  • Can get information about files
  • Can get lists of directory contents
  • Can create files and directories
  • Can delete files and directories

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.

12.2.3: Working with Files and Directories

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]);
    }
  }
}

12.2.4: 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

Exercise 12.2

Take one minute to prepare answers to the following questions:

  1. What is the purpose of the File class?
  2. What is an absolute pathname?
  3. What is a relative pathname?

12.3: Text File I/O

Objectives

At the end of the lesson the student will be able to:

  • Write text to files
  • Read text from files

12.3.1: About Text File I/O

  • Binary files are more efficient for Computers
  • However text files are readable by humans
  • Thus you often use text files rather than binary files
  • Java allows you to use both binary and text files
  • In this section we discuss text file I/O

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

12.3.2: Connecting a Character Output Stream to a File

  • To write to a text file, you need to 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

  • There are many ways to connect a character output stream to a file
  • You can "mix and match" Writer classes to get the functionality you need
  • This list of constructors should give you some idea how this is possible
  • Note that any class ending in the word "Writer" is a Writer class
  • BufferedWriter(Writer out)
    
    FileWriter(File file)
    FileWriter(String pathname)
    FileWriter(String pathname, boolean append)
    
    PrintWriter(Writer out)
    
  • The FileWriter constructor accept a second argument
  • Setting the second argument to true appends data to the file

12.3.3: Procedure for Writing a Text File

  1. Create a File object with a pathname to your file.
  2. File data = new File("data.txt");
    
  3. Connect the file to a stream with a FileWriter.
  4. FileWriter fw = new FileWriter(data);
    

    If you want to append data then use:

    FileWriter fw = new FileWriter(data, true);
    
  5. Add a buffer for the output with a BufferedWriter.
  6. BufferedWriter buf = new BufferedWriter(fw);
    
  7. Add methods to convert binary data to character data with a PrintWriter.
  8. PrintWriter out = new PrintWriter(buf);
    
  9. Write to the file using the print() and println() methods.
  10. 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();
    
  11. Close the streams when finished writing.
  12. out.close();
    

Note that you can nest the constructor calls as shown in the example below

For Example

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");
    }
}

12.3.4: 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

Scanner in = new Scanner(
             new BufferedReader(
             new FileReader(data)));

Mix and Match

  • There are many ways to connect a character input stream to a file
  • You can "mix and match" Reader classes to get the functionality you need
  • This list of constructors should give you some idea how this is possible
  • Recall that any class ending in the word "Reader" is a Reader subclass
  • BufferedReader(Reader in)
    
    FileReader(File file)
    FileReader(String pathname)
    

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.

12.3.5: Procedure For Reading a Text File

  1. Create a File object with a pathname to your file.
  2. File data = new File("data.txt");
    
  3. Connect the file to a stream with a FileReader.
  4. FileReader fr = new FileReader(data);
    
  5. Add a buffer for the input with a BufferedReader.
  6. BufferedReader bin = new BufferedReader(fr);
    
  7. Add a Scanner object to parse the data.
  8. Scanner in = new Scanner(bin);
    
  9. Read data using methods calls for the correct type
  10. int x = in.nextInt();
    
  11. Close the streams when finished reading.
  12. in.close();
    

Note that you can nest the constructor calls as shown in the example below

For Example

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();
    }
}

12.3.6: 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 of 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.

12.3.7: Summary

Writing a Text File

  • To write a text file, you typically layer three streams
    • FileWriter to connect a character stream to the file
    • BufferedWriter to optimize performance
    • PrintWriter class to write binary data as characters
  • Using a File object for the pathname, you often use code that looks like:
  • File data = new File("data.txt");
    PrintWriter out = new PrintWriter(
                      new BufferedWriter(
                      new FileWriter(data)));
    
  • You write to the file using the print() and println() methods.
  • out.println(1234);
    
  • To prevent data from being lost, always close the output stream when finished
  • out.close();
    

Reading a Text File

  • To read a text file, you typically layer two streams
    • FileReader to connect a character stream to the file
    • BufferedReader for performance and to use readLine()
  • Since there is no "PrintReader" class you use a Scanner object
  • Using a File object for file and path names, you often use code that looks like:
  • File data = new File("data.txt");
    Scanner in = new Scanner(
                 new BufferedReader(
                 new FileReader(data)));
    
  • You then read from a stream like reading from a keyboard
  • int x = in.nextInt();
    
  • 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);
    }
    

Exercise 12.3

Take one minute to prepare an answer to the following question:

  1. What does the following snippet of code do?
  2. 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();
    

12.4: Binary File I/O

Objectives

At the end of the lesson the student will be able to:

  • Write and read binary files
  • Write and read objects using serialization

12.4.1: About Binary File I/O

  • Binary file I/O uses the byte-oriented classes
  • Efficient for a computer to store information
  • Hard for a human to read

Some Classes from the OutputStream Hierarchy

OutputStream: Foundation class for reading binary streams
  |
  +--FileOutputStream: Write binary data to a file
  |
  +--ObjectOutputStream: Write objects to a file
  |
  +--FilterOutputStream: Superclass of all filter output streams
       |
       +--BufferedOutputStream: Add a buffer to the stream
       |
       +--DataOutputStream: Write primitive types as binary data

Some Classes from the InputStream Hierarchy

InputStream: Foundation class for writing binary streams
  |
  +--FileInputStream: Read binary data from a file
  |
  +--ObjectInputStream: Read objects from a file
  |
  +--FilterInputStream: Superclass of all filter input streams
       |
       +--BufferedInputStream: Add a buffer to the stream
       |
       +--DataInputStream: Read binary data as primitive types

12.4.2: Binary File Output

  • Opening a binary file for writing is similar to opening a text file for writing, though we use different classes
  • FileOutputStream provides the basic I/O capabilities and opens the file for output
  • FileOutputStream fos =
            new FileOutputStream("data.bin");
    
  • Alternatively, we could open our file for appending data
  • FileOutputStream fos =
            new FileOutputStream("data.bin", true);
    
  • We buffer the I/O for faster output using BufferedOutputStream
  • BufferedOutputStream bos =
            new BufferedOutputStream(fos);
    
  • However, a BufferedOutputStream has minimal capabilities
  • Thus we need to connect our BufferedOutputStream to a more capable object
  • Class ObjectOutputStream is the preferred class
  • ObjectOutputStream out = new ObjectOutputStream(bos);
    
  • Now we can use methods like writeBoolean(), writeInt() and writeDouble() to write data to the file
  • Note that the method for writing strings is called writeUTF
    • Writes a string using UTF-8 encoding
    • UTF-8 is a version of Unicode that uses one byte for ASCII characters
  • Putting all this together, we can create a simple binary-file output class
  • 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 BinaryOutputApp {
        public static void main(String[] args)
                throws IOException {
            File data = new File("data.bin");
            ObjectOutputStream out =
                new ObjectOutputStream(
                new BufferedOutputStream(
                new FileOutputStream(data)));
            out.writeUTF("This is a String");
            out.writeBoolean(true);
            out.writeChar((int)'A');
            out.writeInt(1234);
            out.writeDouble(1.234);
            for (int i = 0; i <= 10; i++)
                out.writeInt(i);
            out.close();
            System.out.println("Finished writing file");
        }
    }
    

12.4.3: Binary File Input

  • Opening a binary file for reading is similar to opening a binary file for writing, though we use input classes
  • FileInputStream provides the basic I/O capabilities and opens the file for input
  • FileInputStream fis =
            new FileInputStream("data.bin");
    
  • We buffer the I/O for faster input using BufferedInputStream
  • BufferedInputStream bis =
            new BufferedInputStream(fis);
    
  • However, a BufferedInputStream has minimal capabilities
  • Thus we need to connect BufferedInputStream to a more capable object
  • Also, we need an ObjectInputStream to read the data written by the ObjectOutputStream
  • ObjectInputStream in = new ObjectInputStream(bis);
    
  • Now we can use methods like readBoolean(), readInt(), readDouble() and readUTF() to read data from the file
  • We need to read data in the same order as it was written
  • 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.*;
    
    class BinaryInputApp {
        public static void main(String[] args)
                throws IOException {
            File data = new File("data.bin");
            ObjectInputStream in =
                new ObjectInputStream(
                new BufferedInputStream(
                new FileInputStream(data)));
            System.out.println(in.readUTF());
            System.out.println(in.readBoolean());
            System.out.println(in.readChar());
            System.out.println(in.readInt());
            System.out.println(in.readDouble());
            for (int i = 0; i <= 10; i++) {
                System.out.print(in.readInt() + ", ");
            }
            System.out.println();
            in.close();
        }
    }
    

12.4.4: Testing for End of an Input Stream

  • Common programming situation is to read data from an input file without knowing how much data the file contains
  • In this case you need to check for the end of the file
  • Three common ways to test for the end of a file:
    • Test for a special character provided by the system that signals the end of the file
    • Put your own sentinel value at the end of the file and test for it
    • Catch an EOFException

EOFException

  • Many (but not all) file-reading methods throw an EOFException
  • Occurs when they try to read beyond the end of the file
  • Many of the ObjectInputStream methods throw an EOFException
  • Can use EOFException in a loop that reads and processes data from a file
  • Loop terminates when an EOFException is thrown
  • Continues normally after the EOFException has been caught

For Example

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
import java.io.*;

class BinaryInputApp2 {
    public static void main(String[] args)
            throws IOException {
        File data = new File("data.bin");
        ObjectInputStream in =
            new ObjectInputStream(
            new BufferedInputStream(
            new FileInputStream(data)));

        try {
            System.out.println(in.readUTF());
            System.out.println(in.readBoolean());
            System.out.println(in.readChar());
            System.out.println(in.readInt());
            System.out.println(in.readDouble());

            while (true) {
                int x = in.readInt();
                System.out.println(x);
            }
        } catch (EOFException e) {
            System.out.println("No more numbers");
        }
        in.close();
    }
}

12.4.5: Object Serialization

  • Java provides a simple way to write and read objects: object serialization
  • When an object is serialized, it is converted into a series of bytes containing the object's data
  • If properly set up, even the fields containing other objects are serialized
  • All of these bytes are saved to a file using an ObjectOutputStream
  • Later on, the object can be read back using an ObjectInputStream

Getting Ready for Object I/O

  • To serialize an object, your class must implement the Serializable interface
  • Serializable is an empty interface that has no methods or fields
  • It is just used to let the compiler know that objects of the class can be serialized
  • Thus, all you do to make a class serializable is add implements Serializable to the class header
  • Note that if you want objects the are referenced in your class serialized, they must implement interface Serializable as well

Further Information

12.4.6: Writing and Reading Objects

  • Note that many classes of the Java API are serializable, including:
  • Let us look at an example of writing and reading objects

Serializable Object

1
2
3
4
5
6
7
8
9
10
11
import java.io.*;
import java.util.Date;

public class SerialObject implements Serializable {
    private String s = "Today is: ";
    private Date d = new Date();

    public String toString() {
        return s + d;
    }
}

Writing and Reading a Serializable Object

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
import java.io.*;

public class SerialApp  {
    public static void main(String[] args)
            throws IOException, ClassNotFoundException {

        // Write an object
        File objData = new File("objdata.bin");
        ObjectOutputStream out =
            new ObjectOutputStream(
            new BufferedOutputStream(
            new FileOutputStream(objData)));
        out.writeObject(new SerialObject());
        out.close();

        // Read an object
        ObjectInputStream in =
            new ObjectInputStream(
            new BufferedInputStream(
            new FileInputStream(objData)));
        SerialObject so =
            (SerialObject) in.readObject();
        System.out.println(so);
        in.close();
    }
}

12.4.7: Summary

  • Writing and reading binary files is a similar process to text files
  • However, classes OutputStream and InputStream are used instead of Writer and Reader
  • The easiest way to check for end-of-file with binary data is to catch an EOFException
  • Java provides a simple way to write and read objects called object serialization
  • To serialize an object, your class must implement the Serializable interface
  • Serializable is an empty interface that has no methods or fields
  • Many classes of the Java API implement the Serializable interface

Exercise 12.4

Take one minute to prepare an answer to the following question:

  1. Given that in is an object of type ObjectInputStream, what does the following snippet of code print?
  2. int x;
    try {
        try {
          while (true) {
              x = in.readInt();
              //do something with x
          }
        }
        catch(EOFException e) {
            System.out.println("End of reading file");
        }
        in.close();
        System.out.println("Continuing normally");
    } catch(IOException e) {
        // handle other problems
    }
    

Wrap Up

Home | WebCT | Announcements | Schedule | Room Policies | Course Info
Help | FAQ's | HowTo's | Links

Last Updated: November 05 2005 @15:55:41