Page 656 - Introduction to Programming with Java: A Problem Solving Approach
P. 656
622 Chapter 15 Files 15.8 Object File I/O
When you can remain within a Java programming environment, that is, use Java programs for all file writ- ing and all file reading, you have an advantage. You can use software that’s built into the Java language to perform the structural conversion between program objects and primitive data streams. This section ex- plains how to use that built-in software.
Enabling Java Objects to be Stored in a File
The java language has built-in software that serializes each object’s data as it goes into a file and unserial- izes that data as it comes out of a file and goes back into object form. Whenever a program writes serialized data into a file, it also writes the recipe it used to serialize that data. That recipe includes the type of the object, the type of each data item, and the sequence in which the data items are stored. When another pro- gram reads serialized data from a file, it also reads the recipe to learn how to reconstruct the object from the serialized data. To enable a class to use Java’s built-in serializing software you must append the following clause to that class’s heading:
implements Serializable
This makes it look like your class is implementing an interface. But this interface doesn’t define any named constants, and it doesn’t require that the class implement any particular methods. It just tags (identifies) the class’s objects as objects needing serialization services. For example, look at the TestObject class in Figure 15.10. Notice that this class implements the Serializable interface.
Writing a Serializable Object to a File
Apago PDF Enhancer
Figure 15.11 contains a simple program that writes a TestObject object to a user-specified file. The first try block statement uses ObjectOutputStream and FileOutputStream instantiations to open the file. Notice that the FileOutputStream constructor has only one parameter. This constructor either creates a new file or over-writes an existing file. There is no append option. (One of this chapter’s projects shows how to append objects to data already in an existing object file.) The second try block statement writes an object to the opened file. The object written is an instance of the class in Figure 15.10. The third statement closes the file.
The catch parameter is an IOException because the ObjectOutputStream constructor and ObjectOutputStream’s writeObject and close methods all throw an IOException. As indi- cated earlier, the FileOutputStream constructor throws a FileNotFoundException, but this ex- ception is derived from IOException. Therefore, using IOException as the catch parameter enables the catch block to catch all of the exceptions that might be thrown from the try block.
Reading a Serializable Object from a File
Figure 15.12’s ReadObject program tries to read data for two objects of the TestObject class from a user-specified file. The program’s code should look familiar since it parallels Figure 15.11’s WriteObject program. However, instead of using FileOutputStream and ObjectOutputStream constructors and the writeObject method, it uses FileInputStream and ObjectInputStream constructors and the readObject method. The only tricky thing is you must include a cast like (TestObject) to convert the reference returned by the readObject method to the specific type that defines the methods you want to use. That cast might throw a ClassNotFoundException, so we include an extra catch block for that exception.