/* * Copyright (c) 2001 Matthew Feldt. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided the copyright notice above is * retained. * * THIS SOFTWARE IS PROVIDED ''AS IS'' AND WITHOUT ANY EXPRESSED OR * IMPLIED WARRANTIES. */ /** * ExternalProperties.java * * Java Examples In A Nutshell Copyright (c) 2000 David Flanagan * Exercise 9-2: * As noted in the previous excercise, the Properties object has store() and * load() methods that allow it to save and restore its state. Define an Exter- * nalizable subclass of Properties that uses these store() and load() methods * as the basis for its writeExternal() and readExternal() methods. In * order to make this work, the writeExternal() method needs to determine * the number of bytes written by the store() method and write this value into * the stream before writing the bytes themselves. This allows the readExternal() * method to know when to stop reading. Also include a version number in the * externalizable data format you use. * * @author Matthew Feldt * @version 1.0, 05/27/2001 18:25 */ package com.feldt.examples.serialization; import java.io.*; import java.util.*; import java.util.zip.*; /** * An extension of the java class Properties that performs external * serialization. */ class ExternalProperties extends Properties { /** class version number */ static final byte version = 1; /** Custom serialization method that writes to ObjectOutput stream. */ public void writeExternal(ObjectOutput out) throws IOException { // move data to byte array to calculate size before serialization ByteArrayOutputStream ostream = new ByteArrayOutputStream(); store(ostream, null); out.writeByte(version); // first, write the version out.writeInt(ostream.size()); // second, write number of bytes out.writeBytes(ostream.toString()); // last, write bytes out.close(); } /** Custom serialization method that reads from ObjectOutput stream. */ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { if (in.readByte() != version) // first, verify version throw new IOException("Incorrect version."); int len = in.readInt(); // second, read number of bytes byte[] buf = new byte[len]; int off = 0, count = 0, total = 0; // last, read bytes while ((count = in.read(buf, off+total, len-total)) != -1) { total += count; if (total >= len) break; } // if total bytes read isn't equal to the len, throw IOException error if (total != len) throw new IOException("Serialization error. Read " + total + " bytes, expected " + len + "."); load(new ByteArrayInputStream(buf)); in.close(); } /** test class */ static class Test { public static void main(String[] args) { final String FILE_NAME = "ep.out"; final int SIZE = 1000; ExternalProperties ep = new ExternalProperties(); // create a large enough property hash to test readExternal() for (int i = 0; i < SIZE; i++) { Integer num = new Integer(i); ep.setProperty(num.toString(), num.toString()); } try { ep.writeExternal( new ObjectOutputStream(new FileOutputStream(FILE_NAME))); ExternalProperties copy = new ExternalProperties(); copy.readExternal( new ObjectInputStream(new FileInputStream(FILE_NAME))); //System.out.println(copy); // uncomment to print all SIZE ints if (copy.equals(ep)) System.out.println("Copies equal."); } catch(IOException e) { System.err.println(e.getMessage()); } catch(ClassNotFoundException e) { System.err.println(e.getMessage()); } } } }