23.07.2013 Views

Java IO.pdf - Nguyen Dang Binh

Java IO.pdf - Nguyen Dang Binh

Java IO.pdf - Nguyen Dang Binh

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Java</strong> I/O<br />

Let's look closer at the serialization parts of this program. What does it mean to serialize<br />

ZipFile? Internally a ZipFile object is a filename and a long integer that serves as a native<br />

file descriptor to interface with the native zlib library. File descriptors have no state that<br />

would make sense across multiple runs of the same program or from one machine to the next.<br />

This is why ZipFile is not itself declared serializable. However, if you know the filename,<br />

you can create a new ZipFile object that is the same for all practical purposes.<br />

This is the approach Example 11.3 takes. To serialize an object, the writeObject() method<br />

writes the filename onto the output stream. The readObject() method reads this name back<br />

in and recreates the object. When readObject() is invoked, the virtual machine creates a<br />

new SerializableZipFile object out of thin air; no constructor is invoked. The zf field is<br />

set to null. Next, the private readObject() method of this object is called. The value of<br />

filename is read from the stream. Finally, a new ZipFile object is created from the filename<br />

and assigned to zf.<br />

This scheme isn't perfect. In particular, the whole thing may come crashing down if the actual<br />

file that's referred to isn't present when the object is deserialized. This might happen if the<br />

actual file was deleted in between the time the object was written and the time it was read, for<br />

example. However, this will only result in an <strong>IO</strong>Exception, which the client programmer<br />

should be ready for in any case.<br />

The main() method tests this scheme by creating a serializable zip file with a name passed in<br />

from the command line. Then the serializable zip file is serialized. Next the<br />

SerializableZipFile object is deserialized from the same byte array it was previously<br />

written into. Here's the result:<br />

D:\JAVA>java SerializableZipFile test.zip<br />

Wrote object!<br />

Read object!<br />

11.8.2 The default WriteObject( ) and defaultReadObject( ) Methods<br />

Sometimes rather than changing the format of an object that's serialized, all you want to do is<br />

add some additional information, perhaps something that isn't normally serialized, like a static<br />

field. In this case, you can use ObjectOutputStream's defaultWriteObject() method to<br />

write the state of the object, then use ObjectOutputStream's defaultReadObject() method<br />

to read the state of the object. After this is done, you can perform any custom work you need<br />

to do on serialization or deserialization.<br />

public final void defaultReadObject()<br />

throws <strong>IO</strong>Exception, ClassNotFoundException, NotActiveException<br />

public final void defaultWriteObject() throws <strong>IO</strong>Exception<br />

For example, let's suppose an application that would otherwise be serializable contains a<br />

Socket field. As well as this field, assume it contains more than a few other complex fields,<br />

so that serializing it by hand, while possible, would be onerous. It might look something like<br />

this:<br />

254

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!