CIS-180 Laboratory Project

File I/O



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