CIS-180 Laboratory Project
File I/O
Objectives
- To learn about object serialization
- To learn how to read and write objects from disk
- To introduce the concepts of exceptions and exception handling
- To apply all of the above in the AddressBook application
Serialization
Object serialization is the process of saving an object's state to a sequence of bytes,
as well as the process of rebuilding those bytes into a live object at some future time.
If a serialized object's fields contain references to other objects, those objects are
included when the object is serialized. For example, if an AddressBook object holds
references to ContactLists, and the ContactLists hold references to Contacts, serializing
the AddressBook object will save everything including the Contacts and ContactLists to
a sequence of bytes.
All that is needed is that all objects to be serialized belong to Serializable classes,
otherwise an error will occur. A serializable class is one that implements the Serializable
interface. The interface does not contain any methods, it is just a marker to indicate that
objects of the class may be serialized. Therefore it is enough that the class simply declare
that it implements Serializable. For example:
public class AddressBook implements Serializable {
// ...
}
If the AddressBook contains ContactLists, and ContactLists contain Contacts,
the ContactList and Contact classes must also implement
the Serializable interface.
Object Input and Output Streams
Object serialization occurs when an object is written to an ObjectOutputStream or
read from an ObjectInputStream. The ObjectOutputSteams and ObjectInputStreams perform
the serialization and rebuilding of objects, respectively, and use other stream objects
for reading and writing the sequence of bytes. If the objects are to be stored and retrieved from
disk, FileOutputStreams and FileInputStreams are used. If we want to write an AddressBook object,
book, to a file called "MyAddressBook", we could use:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("MyAddressBook"));
oos.writeObject(book);
To read the AddressBook object back in from disk, we could use:
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("MyAddressBook"));
AddressBook book = (AddressBook) ois.readObject();
Notice that in this case we obtain the address book object from a file instead of
creating it with the new operator.
Exceptions and Exception Handling
There is one problem with the code examples given above. Certain errors can result which
the programmer has no control over. For example, when attempting to read the address book
from disk the file might not be there because the user deleted it, moved it, or renamed it.
When attempting to write data to the file, errors might result because the disk is full, or
because the user doesn't have permission to write to the folder where the file is located.
These kinds of errors are called exceptions, and Java requires that you write code
to deal with the possibility of exceptions ocurring. Exceptions, in Java, are represented by
objects of the Exception class (or subclasses of Exception). Code that might
cause an exception (such as opening files, reading files, writing files, etc.) must be
contained in a try block, followed by a catch block containing
code to deal with the exception. For example, the code to write the address book object to
a file could be:
try {
// Code that might cause an exception ...
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("MyAddressBook"));
oos.writeObject(book);
} catch (Exception e) {
// Error handlng code ...
e.printStackTrace(); // print out information about the error
}
Exceptions and exception handling are topics that will be covered in detail in CIS181. The
examples above should be enough for your laboratory project.