FileDocCategorySizeDatePackage
Serializer.javaAPI DocExample4596Sat Jan 24 10:44:30 GMT 2004je3.serialization

Serializer.java

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd 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,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.com/javaexamples3.
 */
package je3.serialization;
import java.io.*;

/**
 * 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);
	}
    }
}