/*
* Copyright (c) 2000 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.com/javaexamples2.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Serializable;
/**
* This class defines utility routines that use Java serialization.
*/
public class Serializer {
/**
* Serialize the object o (and any Serializable objects it refers to) and
* store its serialized state in File f.
*/
static void store(Serializable o, File f) throws IOException {
ObjectOutputStream out = // The class for serialization
new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(o); // This method serializes an object graph
out.close();
}
/**
* Deserialize the contents of File f and return the resulting object
*/
static Object load(File f) throws IOException, ClassNotFoundException {
ObjectInputStream in = // The class for de-serialization
new ObjectInputStream(new FileInputStream(f));
return in.readObject(); // This method deserializes an object graph
}
/**
* Use object serialization to make a "deep clone" of the object o. This
* method serializes o and all objects it refers to, and then deserializes
* that graph of objects, which means that everything is copied. This
* differs from the clone() method of an object which is usually implemented
* to produce a "shallow" clone that copies references to other objects,
* instead of copying all referenced objects.
*/
static Object deepclone(final Serializable o) throws IOException,
ClassNotFoundException {
// Create a connected pair of "piped" streams.
// We'll write bytes to one, and them from the other one.
final PipedOutputStream pipeout = new PipedOutputStream();
PipedInputStream pipein = new PipedInputStream(pipeout);
// Now define an independent thread to serialize the object and write
// its bytes to the PipedOutputStream
Thread writer = new Thread() {
public void run() {
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(pipeout);
out.writeObject(o);
} catch (IOException e) {
} finally {
try {
out.close();
} catch (Exception e) {
}
}
}
};
writer.start(); // Make the thread start serializing and writing
// Meanwhile, in this thread, read and deserialize from the piped
// input stream. The resulting object is a deep clone of the original.
ObjectInputStream in = new ObjectInputStream(pipein);
return in.readObject();
}
/**
* This is a simple serializable data structure that we use below for
* testing the methods above
*/
public static class DataStructure implements Serializable {
String message;
int[] data;
DataStructure other;
public String toString() {
String s = message;
for (int i = 0; i < data.length; i++)
s += " " + data[i];
if (other != null)
s += "\n\t" + other.toString();
return s;
}
}
/** This class defines a main() method for testing */
public static class Test {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
// Create a simple object graph
DataStructure ds = new DataStructure();
ds.message = "hello world";
ds.data = new int[] { 1, 2, 3, 4 };
ds.other = new DataStructure();
ds.other.message = "nested structure";
ds.other.data = new int[] { 9, 8, 7 };
// Display the original object graph
System.out.println("Original data structure: " + ds);
// Output it to a file
File f = new File("datastructure.ser");
System.out.println("Storing to a file...");
Serializer.store(ds, f);
// Read it back from the file, and display it again
ds = (DataStructure) Serializer.load(f);
System.out.println("Read from the file: " + ds);
// Create a deep clone and display that. After making the copy
// modify the original to prove that the clone is "deep".
DataStructure ds2 = (DataStructure) Serializer.deepclone(ds);
ds.other.message = null;
ds.other.data = null; // Change original
System.out.println("Deep clone: " + ds2);
}
}
}
|