0
votes

I'm making a Java application that has basic Saving / Opening capabilities. All I need to save is the instance of my class ModeleImage which is a Singleton. My saving apparently works and looks like this:

ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(ModeleImage.getInstance());
outputStream.flush();
outputStream.close();

Now I'm trying to open that file with ObjectInputStream. I'm not sure if there's a way to simply replace my Singleton (ModeleImage) with the saved one but right now I'm only trying to copy and replace each attribute. My opening looks like this:

FileInputStream fis = new FileInputStream(fileChooser.getSelectedFile());
ObjectInputStream ois = new ObjectInputStream(fis);

//Get each attribute from the file and set them in my existing ModeleImage Singleton

ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage());
ModeleImage.getInstance().setLargeurImage(((ModeleImage) ois.readObject()).getLargeurImage());
ModeleImage.getInstance().setHauteurImage(((ModeleImage) ois.readObject()).getHauteurImage());
ModeleImage.getInstance().setxImage(((ModeleImage) ois.readObject()).getxImage());
ModeleImage.getInstance().setyImage(((ModeleImage) ois.readObject()).getyImage());

I also put try/catch around each. The problem is that my opening part catches an IOException when trying to replace attributes.

ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage());
//This catches an IOException

What am I doing wrong? Is it because it's a Singleton or am I misunderstanding how ObjectInputStream and readObject() work?

4
EDIT: Actually I just found out my serialization simply doesn't work when I'm trying to save. I tried opening my saved file with a text editor and it starts with: java.io.NotSerializableException - user1088509
EDIT 2: I forgot to implement Serializable in my ModeleImage class. Now the saved file has no error but is tiny (205 bytes) and contains the name of the fields but not their value. One of the field is an image so the file should be pretty big. - user1088509

4 Answers

1
votes

By using a built-in feature of the serialization mechanism, you can enhance the normal process by providing two methods inside class file. Those methods are:

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

Implement this methods by ModeleImage class and you will control all aspects of serialization and have access to internal state of singleton.

0
votes

You should only be calling readObject() once since you only wrote one object:

ModeleImage image = ois.readObject();
ModeleImage.getInstance().setImage((image.getImage());
ModeleImage.getInstance().setLargeurImage(image.getLargeurImage());
ModeleImage.getInstance().setHauteurImage((image.getHauteurImage());
ModeleImage.getInstance().setxImage(image.getxImage());
ModeleImage.getInstance().setyImage(image.getyImage());
0
votes

What you should do is have a static block that checks an instance of your class that you serialized. If it can, find it, it sets it to your singleton instance (thus making sure you load the one from the file). If it can't find it (perhaps first time your program is launching), then it should create an instance and assign it to your singleton variable.

You could create a save method or what not, or override the finalize method to save off your singleton so that way you can check for it in the static block on next time it is class loaded.

Make sense?

0
votes

Implement readResolve on your serializable Singleton class to ensure there is only ever a single instance and override the properties there, i.e.

private Object readResolve() throws ObjectStreamException
{
    instance.setImage(getImage());
    instance.setLargeurImage(getLargeurImage());
    ... 
    return instance;
}

this concept is described nicely on http://www.javalobby.org/java/forums/t17491.html or check out http://docs.oracle.com/javase/1.3/docs/guide/serialization/spec/input.doc6.html for more on readResolve(). Hope that helps.