0

我正在制作一个具有基本保存/打开功能的 Java 应用程序。我需要保存的只是我的类ModeleImage的实例,它是一个 Singleton。我的储蓄显然有效,看起来像这样:

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

现在我正在尝试使用 ObjectInputStream 打开该文件。我不确定是否有办法简单地将我的 Singleton (ModeleImage) 替换为保存的,但现在我只是尝试复制和替换每个属性。我的开场白是这样的:

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());

我也把 try/catch 放在每一个周围。问题是我的开头部分在尝试替换属性时捕获了 IOException。

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

我究竟做错了什么?是因为它是单例还是我误解了 ObjectInputStream 和 readObject() 的工作原理?

4

4 回答 4

1

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.

于 2011-12-08T20:50:38.613 回答
0

你应该只调用readObject()一次,因为你只写了一个对象:

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());
于 2011-12-08T21:01:28.313 回答
0

在您的可序列化 Singleton 类上实现 readResolve 以确保只有一个实例并覆盖那里的属性,即

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

这个概念在http://www.javalobby.org/java/forums/t17491.html上有很好的描述,或者查看http://docs.oracle.com/javase/1.3/docs/guide/serialization/spec/input。 doc6.html了解有关 readResolve() 的更多信息。希望有帮助。

于 2011-12-08T21:37:27.093 回答
0

您应该做的是有一个静态块来检查您序列化的类的实例。如果可以,找到它,将其设置为您的单例实例(从而确保从文件中加载该实例)。如果找不到它(可能是您的程序第一次启动时),那么它应该创建一个实例并将其分配给您的单例变量。

您可以创建一个保存方法或其他方法,或者覆盖 finalize 方法以保存您的单例,这样您就可以在下次加载类时在静态块中检查它。

说得通?

于 2011-12-08T21:13:17.680 回答