Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как десериализовать объекты более старой версии? 
:(
    Опции темы
Barvetal
Дата 22.1.2009, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 181
Регистрация: 31.10.2005

Репутация: нет
Всего: 5



Всем добрый день!

У меня есть структура данных, которая используется в двух приложениях: в одном эта структура создаётся и правится, в другом читается.

Соответственно, в первом приложении я свой объект сохраняю в файл:

[SRC java]    public static void saveToFile(MyObject obj, String filePath) {
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        ObjectOutputStream out = null;
        try {
            try {
                fos = new FileOutputStream(filePath);
                bos = new BufferedOutputStream(fos);
                out = new ObjectOutputStream(bos);
                out.writeObject(obj);
            } finally {
                out.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }[/SRC]

Во втором приложении читаю объект аналогичным образом (через in.readObject();).

Всё вроде хорошо, но беспокоит следующее:
Допустим, я написал новую версию системы. В новой версии класс MyObject изменился (например, добавилось новое поле, изменился тип существующего или какое-то поле было удалено).

Как мне из новой версии программы открыть старую версию класса MyObject? Ведь определение то класса изменилось!!!
PM MAIL   Вверх
AndrewMormysh
Дата 22.1.2009, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 8.2.2008

Репутация: 1
Всего: 1



Думаю достаточно будет подложить приложению-ридеру старый класс, чтобы он его использовал для десериализации объекта.
PM MAIL   Вверх
Temdegon
Дата 22.1.2009, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



При попытке десериализации ты получаешь InvalidClassException? Или тебе именно нужно обеспечить совместимость как со старой версией класса так и с новой?
PM MAIL   Вверх
Barvetal
Дата 22.1.2009, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 181
Регистрация: 31.10.2005

Репутация: нет
Всего: 5



Цитата(Temdegon @ 22.1.2009,  17:56)
При попытке десериализации ты получаешь InvalidClassException? Или тебе именно нужно обеспечить совместимость как со старой версией класса так и с новой?

Нет, достаточно только чтобы новая версия приложения успешно разруливала старые классы и инициировала недостающие поля значениями по умолчанию
PM MAIL   Вверх
Temdegon
Дата 22.1.2009, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 429
Регистрация: 11.10.2008
Где: Minsk

Репутация: 7
Всего: 9



Я знаю, что есть такая штука: поменял что-то незначительное в классе (что никак не могло повлиять на сам процесс сериализации), и старые данные уже не читаются, т.к. для каждого сериализуемого класса на этапе компиляции определяется поле 
Код

private static final long serialVersionUID

и это поле сериализуется. код перед тем как десериализовать данные проверяет, совпадает ли это поле с полем класса. Если да, то делается десериализация, если нет - выкидывается эксепшн. Это ограничение можно обойти явно обьявив эту переменную в сериализуемом классе. Тогда все будет читаться всегда. Но этот метод не подходит для твоего случая, если ты хочешь менять типы полей, добавлять новые, т.е. делать что-то что явно повлияет на саму сериализацию. Даже если метод прокатит и данные десериализуются без исключения, маловероятно что это будет сделано правильно.

Добавлено через 4 минуты и 34 секунды
Возможно в твоем случае имеет смысл использовать Экстернализацию вместо сериализации (java.io.Externalizable). 
PM MAIL   Вверх
COVD
Дата 22.1.2009, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Возможно, для этого удобнее сериализовать в виде xml. Например, java.beans.XMLEncoder .. XMLDecoder . Если при десериализации обнаруживается , что сеттер отсутствует, то выдается сообщение и восстановление продолжается. Обьект должен быть бином. Инициировать новые поля надо самостоятельно.

Это сообщение отредактировал(а) COVD - 22.1.2009, 19:05
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0608 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.