Java/File Input Output/Serialization — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 09:02, 1 июня 2010
Содержание
- 1 Assists with the serialization process and performs additional functionality based on serialization.
- 2 Computes all the class serialVersionUIDs under the jboss home directory.
- 3 Create a serialized output file
- 4 Object Serialization
- 5 Reconstructing an externalizable object
- 6 Serial Demo
- 7 Serializable
- 8 Serializable Enumeration
- 9 Serialization Utilities
- 10 Serialization with ObjectInputStream and ObjectOutputStream
- 11 Serializer class
- 12 Simple use of Externalizable and a pitfall
- 13 This program shows how to use getSerialVersionUID
- 14 Working with Serialization
Assists with the serialization process and performs additional functionality based on serialization.
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; /**
*Assists with the serialization process and performs additional functionality based * on serialization.
**
-
*
- Deep clone using serialization *
- Serialize managing finally and IOException *
- Deserialize managing finally and IOException *
*
* <p>This class throws exceptions for invalid null
inputs.
* Each method documents its behaviour in more detail.
* * @author * @author Daniel L. Rall * @author Stephen Colebourne * @author Jeff Varszegi * @author Gary Gregory * @since 1.0 * @version $Id: SerializationUtils.java 512889 2007-02-28 18:18:20Z dlr $ */
public class SerializationUtils {
/***
SerializationUtils instances should NOT be constructed in standard programming.
* Instead, the class should be used as SerializationUtils.clone(object)
.
**
This constructor is public to permit tools that require a JavaBean instance * to operate.
* @since 2.0 */ public SerializationUtils() { super(); } // Clone //----------------------------------------------------------------------- /***
Deep clone an Object
using serialization.
**
This is many times slower than writing clone methods by hand
* on all objects in your object graph. However, for complex object
* graphs, or for those that don"t support deep cloning this can
* be a simple alternative implementation. Of course all the objects
* must be Serializable
.
*
* @param object the Serializable
object to clone
* @return the cloned object
* @throws SerializationException (runtime) if the serialization fails
*/
public static Object clone(Serializable object) {
return deserialize(serialize(object));
}
// Serialize
//-----------------------------------------------------------------------
/**
* Serializes an Object
to the specified stream.
**
The stream will be closed once the object is written. * This avoids the need for a finally clause, and maybe also exception * handling, in the application code.
**
The stream passed in is not buffered internally within this method. * This is the responsibility of your application if desired.
* * @param obj the object to serialize to bytes, may be null * @param outputStream the stream to write to, must not be null * @throws IllegalArgumentException if*outputStream
isnull
* @throws SerializationException (runtime) if the serialization fails */ public static void serialize(Serializable obj, OutputStream outputStream) { if (outputStream == null) { throw new IllegalArgumentException("The OutputStream must not be null"); } ObjectOutputStream out = null; try { // stream closed in the finally out = new ObjectOutputStream(outputStream); out.writeObject(obj); } catch (IOException ex) { throw new RuntimeException(ex); } finally { try { if (out != null) { out.close(); } } catch (IOException ex) { // ignore close exception } } } /**
Serializes an Object
to a byte array for
* storage/serialization.
* * @param obj the object to serialize to bytes * @return a byte[] with the converted Serializable * @throws SerializationException (runtime) if the serialization fails */ public static byte[] serialize(Serializable obj) { ByteArrayOutputStream baos = new ByteArrayOutputStream(512); serialize(obj, baos); return baos.toByteArray(); } // Deserialize //----------------------------------------------------------------------- /***
Deserializes an Object
from the specified stream.
**
The stream will be closed once the object is written. This * avoids the need for a finally clause, and maybe also exception * handling, in the application code.
**
The stream passed in is not buffered internally within this method. * This is the responsibility of your application if desired.
* * @param inputStream the serialized object input stream, must not be null * @return the deserialized object * @throws IllegalArgumentException if*inputStream
isnull
* @throws SerializationException (runtime) if the serialization fails */ public static Object deserialize(InputStream inputStream) { if (inputStream == null) { throw new IllegalArgumentException("The InputStream must not be null"); } ObjectInputStream in = null; try { // stream closed in the finally in = new ObjectInputStream(inputStream); return in.readObject(); } catch (ClassNotFoundException ex) { throw new RuntimeException(ex); } catch (IOException ex) { throw new RuntimeException(ex); } finally { try { if (in != null) { in.close(); } } catch (IOException ex) { // ignore close exception } } } /**
Deserializes a single Object
from an array of bytes.
* * @param objectData the serialized object, must not be null * @return the deserialized object * @throws IllegalArgumentException ifobjectData
isnull
* @throws SerializationException (runtime) if the serialization fails */ public static Object deserialize(byte[] objectData) { if (objectData == null) { throw new IllegalArgumentException("The byte[] must not be null"); } ByteArrayInputStream bais = new ByteArrayInputStream(objectData); return deserialize(bais); }
}
</source>
Computes all the class serialVersionUIDs under the jboss home directory.
<source lang="java">
/*
* JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.io.Serializable; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.security.CodeSource; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; /**
* A tool/service that computes all the class serialVersionUIDs under the jboss * home directory. * * @author Scott.Stark@jboss.org * @author Dimitris.Andreadis@jboss.org * @version $Revision: 84164 $ */
public class SerialVersionUID {
/** A jdk logger so that only this + ClassVersionInfo are needed */ static Logger log = Logger.getLogger("SerialVersionUID"); static void buildJarSet(File dir, HashSet jarFiles) throws MalformedURLException { File[] files = dir.listFiles(); int count = files != null ? files.length : 0; System.out.println("Checking dir: " + dir + ", count=" + count); for (int n = 0; n < count; n++) { File child = files[n]; // Ignore the server tmp directory if (child.isDirectory() && child.getName().equals("tmp") == false) buildJarSet(child, jarFiles); else if (child.getName().endsWith(".jar")) jarFiles.add(child.toURL()); } } /** * Build a TreeMap of the class name to ClassVersionInfo * * @param jar * @param classVersionMap * TreeMap<String, ClassVersionInfo> for serializable classes * @param cl - * the class loader to use * @throws IOException * thrown if the jar cannot be opened */ static void generateJarSerialVersionUIDs(URL jar, TreeMap classVersionMap, ClassLoader cl, String pkgPrefix) throws IOException { String jarName = jar.getFile(); JarFile jf = new JarFile(jarName); Enumeration entries = jf.entries(); while (entries.hasMoreElements()) { JarEntry entry = (JarEntry) entries.nextElement(); String name = entry.getName(); if (name.endsWith(".class") && name.startsWith(pkgPrefix)) { name = name.substring(0, name.length() - 6); String classname = name.replace("/", "."); try { log.fine("Creating ClassVersionInfo for: " + classname); ClassVersionInfo cvi = new ClassVersionInfo(classname, cl); log.fine(cvi.toString()); if (cvi.getSerialVersion() != 0) { ClassVersionInfo prevCVI = (ClassVersionInfo) classVersionMap.put(classname, cvi); if (prevCVI != null) { if (prevCVI.getSerialVersion() != cvi.getSerialVersion()) { log.severe("Found inconsistent classes, " + prevCVI + " != " + cvi + ", jar: " + jarName); } } if (cvi.getHasExplicitSerialVersionUID() == false) { log.warning("No explicit serialVersionUID: " + cvi); } } } catch (OutOfMemoryError e) { log.log(Level.SEVERE, "Check the MaxPermSize", e); } catch (Throwable e) { log.log(Level.FINE, "While loading: " + name, e); } } } jf.close(); } /** * Create a Map<String, ClassVersionInfo> for the jboss dist jars. * * @param jbossHome - * the jboss dist root directory * @return Map<String, ClassVersionInfo> * @throws IOException */ public static Map generateJBossSerialVersionUIDReport(File jbossHome) throws IOException { // Obtain the jars from the /lib, common/ and /server/all locations HashSet jarFiles = new HashSet(); File lib = new File(jbossHome, "lib"); buildJarSet(lib, jarFiles); File common = new File(jbossHome, "common"); buildJarSet(common, jarFiles); File all = new File(jbossHome, "server/all"); buildJarSet(all, jarFiles); URL[] cp = new URL[jarFiles.size()]; jarFiles.toArray(cp); ClassLoader parent = Thread.currentThread().getContextClassLoader(); URLClassLoader completeClasspath = new URLClassLoader(cp, parent); TreeMap classVersionMap = new TreeMap(); Iterator jarIter = jarFiles.iterator(); while (jarIter.hasNext()) { URL jar = (URL) jarIter.next(); try { generateJarSerialVersionUIDs(jar, classVersionMap, completeClasspath, ""); } catch (IOException e) { log.info("Failed to process jar: " + jar); } } return classVersionMap; } /** * Create a Map<String, ClassVersionInfo> for the jboss dist jars. * * @param j2eeHome - * the j2ee ri dist root directory * @return Map<String, ClassVersionInfo> * @throws IOException */ public static Map generateRISerialVersionUIDReport(File j2eeHome) throws IOException { // Obtain the jars from the /lib HashSet jarFiles = new HashSet(); File lib = new File(j2eeHome, "lib"); buildJarSet(lib, jarFiles); URL[] cp = new URL[jarFiles.size()]; jarFiles.toArray(cp); ClassLoader parent = Thread.currentThread().getContextClassLoader(); URLClassLoader completeClasspath = new URLClassLoader(cp, parent); TreeMap classVersionMap = new TreeMap(); Iterator jarIter = jarFiles.iterator(); while (jarIter.hasNext()) { URL jar = (URL) jarIter.next(); try { generateJarSerialVersionUIDs(jar, classVersionMap, completeClasspath, "javax"); } catch (IOException e) { log.info("Failed to process jar: " + jar); } } return classVersionMap; } /** * Generate a mapping of the serial version UIDs for the serializable classes * under the jboss dist directory * * @param args - * [0] = jboss dist root directory * @throws Exception */ public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("Usage: jboss-home | -rihome ri-home"); System.exit(1); } File distHome = new File(args[0]); Map classVersionMap = null; if (args.length == 2) classVersionMap = generateRISerialVersionUIDReport(distHome); else classVersionMap = generateJBossSerialVersionUIDReport(distHome); // Write the map out the object file log.info("Total classes with serialVersionUID != 0: " + classVersionMap.size()); FileOutputStream fos = new FileOutputStream("serialuid.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(classVersionMap); fos.close(); }
} /**
* Encapsulates a class serialVersionUID and codebase. * * @author Scott.Stark@jboss.org * @version $Revision: 81038 $ */
class ClassVersionInfo implements Serializable {
static final long serialVersionUID = 2036506209171911437L; /** The named class serialVersionUID as returned by ObjectStreamClass */ private long serialVersion; /** The binary class name */ private String name; private boolean hasExplicitSerialVersionUID; private transient URL location; public ClassVersionInfo(String name, ClassLoader loader) throws ClassNotFoundException { this.name = name; Class c = loader.loadClass(name); CodeSource cs = c.getProtectionDomain().getCodeSource(); if (cs != null) location = cs.getLocation(); if (c.isInterface() == false) { ObjectStreamClass osc = ObjectStreamClass.lookup(c); if (osc != null) { serialVersion = osc.getSerialVersionUID(); try { c.getDeclaredField("serialVersionUID"); hasExplicitSerialVersionUID = true; } catch (NoSuchFieldException e) { hasExplicitSerialVersionUID = false; } } } } public long getSerialVersion() { return serialVersion; } public boolean getHasExplicitSerialVersionUID() { return hasExplicitSerialVersionUID; } public String getName() { return name; } public String toString() { StringBuffer tmp = new StringBuffer("ClassVersionInfo"); tmp.append("{"); tmp.append("serialVersion="); tmp.append(serialVersion); tmp.append(", hasExplicitSerialVersionUID="); tmp.append(hasExplicitSerialVersionUID); tmp.append(", name="); tmp.append(name); tmp.append(", location="); tmp.append(location); tmp.append("}"); return tmp.toString(); } /** * Usage: ClassVersionInfo class-name * * Locate the class name on the thread context class loader classpath and * print its version info. * * @param args * [0] = class-name */ public static void main(String[] args) throws Exception { if (args.length == 0) throw new IllegalStateException("Usage: ...ClassVersionInfo class-name"); ClassLoader loader = Thread.currentThread().getContextClassLoader(); ClassVersionInfo info = new ClassVersionInfo(args[0], loader); System.out.println(info); }
}
</source>
Create a serialized output file
<source lang="java">
// : c12:FreezeAlien.java // Create a serialized output file. // {Clean: X.file} // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.io.FileOutputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; public class FreezeAlien {
// Throw exceptions to console: public static void main(String[] args) throws Exception { ObjectOutput out = new ObjectOutputStream( new FileOutputStream("X.file")); Alien zorcon = new Alien(); out.writeObject(zorcon); }
} ///:~ class Alien implements Serializable { } ///:~
</source>
Object Serialization
<source lang="java">
/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * -Redistribution of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class CardReader {
public static void main(String[] args) { Card3 card = new Card3(12, Card3.SPADES); System.out.println("Card to write is: " + card); try { FileOutputStream out = new FileOutputStream("card.out"); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(card); oos.flush(); } catch (Exception e) { System.out.println("Problem serializing: " + e); } Card3 acard = null; try { FileInputStream in = new FileInputStream("card.out"); ObjectInputStream ois = new ObjectInputStream(in); acard = (Card3) (ois.readObject()); } catch (Exception e) { System.out.println("Problem serializing: " + e); } System.out.println("Card read is: " + acard); }
} class Card3 implements Serializable {
private int suit = UNASSIGNED; private int number = UNASSIGNED; public final static int UNASSIGNED = -1; public final static int DIAMONDS = 1; public final static int CLUBS = 2; public final static int HEARTS = 3; public final static int SPADES = 4; public final static int ACE = 1; public final static int KING = 13; public Card3(int number, int suit) { if (isValidNumber(number)) { this.number = number; } else { //Error } if (isValidSuit(suit)) { this.suit = suit; } else { //Error } } public int getSuit() { return suit; } public int getNumber() { return number; } public static boolean isValidNumber(int number) { if (number >= ACE && number <= KING) { return true; } else { return false; } } public static boolean isValidSuit(int suit) { if (suit >= DIAMONDS && suit <= SPADES) { return true; } else { return false; } } public boolean equals(Object obj) { if (obj instanceof Card3) { Card3 card = (Card3) obj; if (card.getNumber() == this.number && card.getSuit() == this.suit) { return true; } else { return false; } } else { return false; } } public int hashCode() { return number * suit; } public String toString() { return numberToString(this.number) + " of " + suitToString(this.suit); } public static String numberToString(int number) { String result = ""; switch (number) { case ACE: result = "Ace"; break; case 2: result = "Two"; break; case 3: result = "Three"; break; case 4: result = "Four"; break; case 5: result = "Five"; break; case 6: result = "Six"; break; case 7: result = "Seven"; break; case 8: result = "Eight"; break; case 9: result = "Nine"; break; case 10: result = "Ten"; break; case 11: result = "Jack"; break; case 12: result = "Queen"; break; case KING: result = "King"; break; case UNASSIGNED: result = "Invalid Number"; break; } return result; } public static String suitToString(int suit) { String result = ""; switch (suit) { case DIAMONDS: result = "Diamonds"; break; case CLUBS: result = "Clubs"; break; case HEARTS: result = "Hearts"; break; case SPADES: result = "Spades"; break; case UNASSIGNED: result = "Invalid Suit"; break; } return result; }
}
</source>
Reconstructing an externalizable object
<source lang="java">
// : c12:Blip3.java // Reconstructing an externalizable object. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.io.Externalizable; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; public class Blip3 implements Externalizable {
private int i; private String s; // No initialization public Blip3() { System.out.println("Blip3 Constructor"); // s, i not initialized } public Blip3(String x, int a) { System.out.println("Blip3(String x, int a)"); s = x; i = a; // s & i initialized only in nondefault constructor. } public String toString() { return s + i; } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("Blip3.writeExternal"); // You must do this: out.writeObject(s); out.writeInt(i); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("Blip3.readExternal"); // You must do this: s = (String) in.readObject(); i = in.readInt(); } public static void main(String[] args) throws IOException, ClassNotFoundException { System.out.println("Constructing objects:"); Blip3 b3 = new Blip3("A String ", 47); System.out.println(b3); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream( "Blip3.out")); System.out.println("Saving object:"); o.writeObject(b3); o.close(); // Now get it back: ObjectInputStream in = new ObjectInputStream(new FileInputStream( "Blip3.out")); System.out.println("Recovering b3:"); b3 = (Blip3) in.readObject(); System.out.println(b3); }
} ///:~
</source>
Serial Demo
<source lang="java">
/* Database Programming with JDBC and Java, Second Edition By George Reese ISBN: 1-56592-616-1 Publisher: O"Reilly
- /
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /**
* Example 6-2. */
public class SerialDemo implements Serializable {
static public void main(String[] args) { try { { // Save a SerialDemo object with a value of 5. FileOutputStream f = new FileOutputStream("/tmp/testing"); ObjectOutputStream s = new ObjectOutputStream(f); SerialDemo d = new SerialDemo(5); s.writeObject(d); s.flush(); } { // Now restore it and look at the value. FileInputStream f = new FileInputStream("/tmp/testing"); ObjectInputStream s = new ObjectInputStream(f); SerialDemo d = (SerialDemo) s.readObject(); System.out.println("SerialDemo.getVal() is: " + d.getVal()); } } catch (Exception e) { e.printStackTrace(); } } int test_val = 7; // value defaults to 7 public SerialDemo() { super(); } public SerialDemo(int x) { super(); test_val = x; } public int getVal() { return test_val; }
}
</source>
Serializable
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
/** Demo of a data class that will be used as a JavaBean or as a data
* class in a Servlet container; making it Serializable allows * it to be saved ("serialized") to disk or over a network connection. */
public class SerializableUser implements java.io.Serializable {
public String name; public String address; public String country; public String phoneNum; // other fields, and methods, here... static final long serialVersionUID = -7978489268769667877L;
}
</source>
Serializable Enumeration
<source lang="java">
/*
* JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.NoSuchElementException; /**
* ??? * * @author ??? * @version $Revision: 2800 $ */
@SuppressWarnings("unchecked") public class SerializableEnumeration
extends ArrayList implements Enumeration
{
/** The serialVersionUID */ private static final long serialVersionUID = 8678951571196067510L; private int index; public SerializableEnumeration () { index = 0; } public SerializableEnumeration (Collection c) { super(c); index = 0; } public SerializableEnumeration (int initialCapacity) { super(initialCapacity); index = 0; } public boolean hasMoreElements() { return (index < size()); } public Object nextElement() throws NoSuchElementException { try { Object nextObj = get(index); index++; return nextObj; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { // the only thing to write is the index field out.defaultWriteObject(); } private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { in.defaultReadObject(); }
}
</source>
Serialization Utilities
<source lang="java">
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SerializationUtils {
public static byte[] serialize(Object obj) { try { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(buffer); oos.writeObject(obj); oos.close(); return buffer.toByteArray(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("error writing to byte-array!"); } } public static Object deserialize(byte[] bytes) throws ClassNotFoundException { try { ByteArrayInputStream input = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(input); return ois.readObject(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("error reading from byte-array!"); } } public static Object serializedCopy(Object obj) { try { return deserialize(serialize(obj)); } catch (ClassNotFoundException e) { throw new RuntimeException("this shouldn"t happen"); } }
}
</source>
Serialization with ObjectInputStream and ObjectOutputStream
<source lang="java">
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; class Employee implements java.io.Serializable {
public String name; public String address; public transient int SSN; public int number; public void mailCheck() { System.out.println("Mailing a check to " + name + " " + address); }
} class SerializeDemo {
public static void main(String[] args) { Employee e = new Employee(); e.name = "A"; e.address = "B"; e.SSN = 11111; e.number = 101; try { FileOutputStream fileOut = new FileOutputStream("employee.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(e); out.close(); fileOut.close(); } catch (IOException i) { i.printStackTrace(); } }
} class DeserializeDemo {
public static void main(String[] args) { Employee e = null; try { FileInputStream fileIn = new FileInputStream("employee.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); e = (Employee) in.readObject(); in.close(); fileIn.close(); } catch (IOException i) { i.printStackTrace(); return; } catch (ClassNotFoundException c) { System.out.println("Employee class not found"); c.printStackTrace(); return; } System.out.println("Name: " + e.name); System.out.println("Address: " + e.address); System.out.println("SSN: " + e.SSN); System.out.println("Number: " + e.number); }
}
</source>
Serializer class
<source lang="java">
/*
* 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.ru/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); } }
}
</source>
Simple use of Externalizable and a pitfall
<source lang="java">
// : c12:Blips.java // Simple use of Externalizable & a pitfall. // {Clean: Blips.out} // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.io.Externalizable; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; class Blip1 implements Externalizable {
public Blip1() { System.out.println("Blip1 Constructor"); } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("Blip1.writeExternal"); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("Blip1.readExternal"); }
} class Blip2 implements Externalizable {
Blip2() { System.out.println("Blip2 Constructor"); } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("Blip2.writeExternal"); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("Blip2.readExternal"); }
} public class Blips {
// Throw exceptions to console: public static void main(String[] args) throws IOException, ClassNotFoundException { System.out.println("Constructing objects:"); Blip1 b1 = new Blip1(); Blip2 b2 = new Blip2(); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream( "Blips.out")); System.out.println("Saving objects:"); o.writeObject(b1); o.writeObject(b2); o.close(); // Now get them back: ObjectInputStream in = new ObjectInputStream(new FileInputStream( "Blips.out")); System.out.println("Recovering b1:"); b1 = (Blip1) in.readObject(); // OOPS! Throws an exception: //! System.out.println("Recovering b2:"); //! b2 = (Blip2)in.readObject(); }
} ///:~
</source>
This program shows how to use getSerialVersionUID
<source lang="java">
import java.io.ObjectStreamClass; /**
* This program shows how to use getSerialVersionUID for a class that isn"t in a * package and thus not findable to the normal "serialver" tool. * * @author Ian Darwin, http://www.darwinsys.ru/ */
public class GetSerVersUID {
static final String ident = "$Id: GetSerVersUID.java,v 1.5 2004/02/09 03:33:53 ian Exp $"; public static void main(String[] av) throws Exception { // First we construct a Class object for the given class Class cl = Class.forName("Candidate"); // Then an ObjectStreamClass for the given class ObjectStreamClass ocl = ObjectStreamClass.lookup(cl); // And use the ObjectStreamClass to get the Class" // unique SerialVersionUID System.out.println("For class " + cl); System.out.println("static final long serialVersionUID = " + ocl.getSerialVersionUID() + "L;"); // must be long // And just for reference... System.out.println("(Must range from " + Long.MIN_VALUE + " to " + Long.MAX_VALUE + ".)"); }
}
</source>
Working with Serialization
<source lang="java">
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class PersisTest extends JFrame implements ActionListener {
ArrayList displayList = new ArrayList();; String pathname; JButton clearBtn, saveBtn, restoreBtn, quitBtn; public static void main(String args[]) { if (args.length == 0) { System.err.println("Usage: java PersisTest filename"); System.exit(-1); } new PersisTest(args[0]).show(); } public PersisTest(String pathname) { super("Save Me"); setDefaultCloseOperation(EXIT_ON_CLOSE); this.pathname = pathname; // Build the GUI. Make this object a listener for all actions. JPanel pan = new JPanel(); clearBtn = new JButton("Clear"); clearBtn.addActionListener(this); pan.add(clearBtn); saveBtn = new JButton("Save"); saveBtn.addActionListener(this); pan.add(saveBtn); restoreBtn = new JButton("Restore"); restoreBtn.addActionListener(this); pan.add(restoreBtn); quitBtn = new JButton("Quit"); quitBtn.addActionListener(this); pan.add(quitBtn); Container c = getContentPane(); c.add(pan, BorderLayout.NORTH); c.add(new ClickPanel(), BorderLayout.CENTER); setSize(350, 200); } public void actionPerformed(ActionEvent e) { if (e.getSource() == clearBtn) { // Repaint with an empty display list. displayList = new ArrayList(); repaint(); } else if (e.getSource() == saveBtn) { // Write display list array list to an object output stream. try { FileOutputStream fos = new FileOutputStream(pathname); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(displayList); oos.flush(); oos.close(); fos.close(); } catch (IOException ex) { System.err.println("Trouble writing display list array list"); } } else if (e.getSource() == restoreBtn) { // Read a new display list array list from an object input stream. try { FileInputStream fis = new FileInputStream(pathname); ObjectInputStream ois = new ObjectInputStream(fis); displayList = (ArrayList) (ois.readObject()); ois.close(); fis.close(); repaint(); } catch (ClassNotFoundException ex) { System.err.println("Trouble reading display list array list"); } catch (IOException ex) { System.err.println("Trouble reading display list array list"); } } else if (e.getSource() == quitBtn) { System.exit(0); } } class ClickPanel extends JPanel { ClickPanel() { MouseListener listener = new MouseAdapter() { public void mousePressed(MouseEvent e) { // Store x and y in display list array list. Point p = new Point(e.getX(), e.getY()); displayList.add(p); } public void mouseReleased(MouseEvent e) { // Store x and y in display list array list, and request // repaint. Point p = new Point(e.getX(), e.getY()); displayList.add(p); repaint(); } }; addMouseListener(listener); } public void paintComponent(Graphics g) { // Clear to white. g.setColor(Color.white); g.fillRect(0, 0, getSize().width, getSize().height); // Traverse display list, drawing 1 rect for each 2 points // in the array list. g.setColor(Color.black); int i = 0; while (i < displayList.size()) { Point p0 = (Point) (displayList.get(i++)); Point p1 = (Point) (displayList.get(i++)); int x = Math.min(p0.x, p1.x); int y = Math.min(p0.y, p1.y); int w = Math.abs(p0.x - p1.x); int h = Math.abs(p0.y - p1.y); g.drawRect(x, y, w, h); } } }
}
</source>