Как заменить существующий объект Singleton на объект из сохраненного файла, используя ObjectInputStream? - PullRequest
0 голосов
/ 09 декабря 2011

Я делаю 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

Что я делаю не так? Это потому, что это Singleton или я неправильно понимаю, как работают ObjectInputStream и readObject ()?

Ответы [ 4 ]

1 голос
/ 09 декабря 2011

Используя встроенную функцию механизма сериализации, вы можете улучшить обычный процесс, предоставив два метода внутри файла класса. Эти методы:

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

Реализуйте эти методы с помощью класса ModeleImage, и вы будете контролировать все аспекты сериализации и иметь доступ к внутреннему состоянию синглтона.

0 голосов
/ 09 декабря 2011

Реализуйте readResolve в вашем сериализуемом классе Singleton, чтобы обеспечить наличие только одного экземпляра и переопределить там свойства, т.е.

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 ().Надеюсь, это поможет.

0 голосов
/ 09 декабря 2011

Что вам нужно сделать, так это иметь статический блок, который проверяет экземпляр вашего класса, который вы сериализовали.Если это возможно, найдите его, он установит его для вашего экземпляра синглтона (таким образом, убедившись, что вы загружаете его из файла).Если он не может найти его (возможно, в первый раз, когда запускается ваша программа), то он должен создать экземпляр и назначить его вашей одноэлементной переменной.

Вы можете создать метод сохранения или что-то другое или переопределитьМетод finalize для сохранения вашего синглтона, чтобы вы могли проверить его в статическом блоке при следующем загрузке класса.

Имеет смысл?

0 голосов
/ 09 декабря 2011

Вы должны вызывать 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());
...