http://www.javapractices.com/topic/TopicAction.do?Id=57
Reading and writing Serializable objects is very similar to reading and writing text:
- it' almost always a good idea to use buffering (default size is 8K)
- it's often possible to use abstract base class references, instead of references to concrete classes
- there's always a need to pay attention to exceptions; in particular, IOException and ClassNotFoundException
Example
Here, a List of String objects is serialized and then deserialized.
import java.io.*; import java.util.*; import java.util.logging.*; /** Uses buffering, and abstract base classes. JDK 7+. */ public class ExerciseSerializableNew { public static void main(String... aArguments) { //create a Serializable List List<String> quarks = Arrays.asList( "up", "down", "strange", "charm", "top", "bottom" ); //serialize the List try ( OutputStream file = new FileOutputStream("quarks.ser"); OutputStream buffer = new BufferedOutputStream(file); ObjectOutput output = new ObjectOutputStream(buffer); ){ output.writeObject(quarks); } catch(IOException ex){ fLogger.log(Level.SEVERE, "Cannot perform output.", ex); } //deserialize the quarks.ser file try( InputStream file = new FileInputStream("quarks.ser"); InputStream buffer = new BufferedInputStream(file); ObjectInput input = new ObjectInputStream (buffer); ){ //deserialize the List List<String> recoveredQuarks = (List<String>)input.readObject(); //display its data for(String quark: recoveredQuarks){ System.out.println("Recovered Quark: " + quark); } } catch(ClassNotFoundException ex){ fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex); } catch(IOException ex){ fLogger.log(Level.SEVERE, "Cannot perform input.", ex); } } // PRIVATE private static final Logger fLogger = Logger.getLogger(ExerciseSerializableNew.class.getPackage().getName()) ; }
Example - JDK 6-
If try-with-resources is not available (JDK 6-), then you must be careful with the close method:
- it always needs to be called, or else resources will leak
- it will automatically flush the stream, if necessary
- calling close on a "wrapper" stream will automatically call close on its underlying stream
- closing a stream a second time has no consequence
Example
Here's the same example as above, but using JDK 6-.
import java.io.*; import java.util.*; import java.util.logging.*; /** JDK before version 7. */ public class ExerciseSerializable { public static void main(String... aArguments) { //create a Serializable List List<String> quarks = Arrays.asList( "up", "down", "strange", "charm", "top", "bottom" ); //serialize the List //note the use of abstract base class references try{ //use buffering OutputStream file = new FileOutputStream("quarks.ser"); OutputStream buffer = new BufferedOutputStream(file); ObjectOutput output = new ObjectOutputStream(buffer); try{ output.writeObject(quarks); } finally{ output.close(); } } catch(IOException ex){ fLogger.log(Level.SEVERE, "Cannot perform output.", ex); } //deserialize the quarks.ser file //note the use of abstract base class references try{ //use buffering InputStream file = new FileInputStream("quarks.ser"); InputStream buffer = new BufferedInputStream(file); ObjectInput input = new ObjectInputStream (buffer); try{ //deserialize the List List<String> recoveredQuarks = (List<String>)input.readObject(); //display its data for(String quark: recoveredQuarks){ System.out.println("Recovered Quark: " + quark); } } finally{ input.close(); } } catch(ClassNotFoundException ex){ fLogger.log(Level.SEVERE, "Cannot perform input. Class not found.", ex); } catch(IOException ex){ fLogger.log(Level.SEVERE, "Cannot perform input.", ex); } } // PRIVATE //Use Java's logging facilities to record exceptions. //The behavior of the logger can be configured through a //text file, or programmatically through the logging API. private static final Logger fLogger = Logger.getLogger(ExerciseSerializable.class.getPackage().getName()) ; }