| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Как десериализовать объекты более старой версии? |
| Автор: Barvetal 22.1.2009, 16:43 |
| Всем добрый день! У меня есть структура данных, которая используется в двух приложениях: в одном эта структура создаётся и правится, в другом читается. Соответственно, в первом приложении я свой объект сохраняю в файл: [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? Ведь определение то класса изменилось!!! |
| Автор: AndrewMormysh 22.1.2009, 17:40 |
| Думаю достаточно будет подложить приложению-ридеру старый класс, чтобы он его использовал для десериализации объекта. |
| Автор: Temdegon 22.1.2009, 17:56 |
| При попытке десериализации ты получаешь InvalidClassException? Или тебе именно нужно обеспечить совместимость как со старой версией класса так и с новой? |
| Автор: Barvetal 22.1.2009, 18:01 | ||
Нет, достаточно только чтобы новая версия приложения успешно разруливала старые классы и инициировала недостающие поля значениями по умолчанию |
| Автор: Temdegon 22.1.2009, 18:52 | ||
Я знаю, что есть такая штука: поменял что-то незначительное в классе (что никак не могло повлиять на сам процесс сериализации), и старые данные уже не читаются, т.к. для каждого сериализуемого класса на этапе компиляции определяется поле
и это поле сериализуется. код перед тем как десериализовать данные проверяет, совпадает ли это поле с полем класса. Если да, то делается десериализация, если нет - выкидывается эксепшн. Это ограничение можно обойти явно обьявив эту переменную в сериализуемом классе. Тогда все будет читаться всегда. Но этот метод не подходит для твоего случая, если ты хочешь менять типы полей, добавлять новые, т.е. делать что-то что явно повлияет на саму сериализацию. Даже если метод прокатит и данные десериализуются без исключения, маловероятно что это будет сделано правильно. Добавлено через 4 минуты и 34 секунды Возможно в твоем случае имеет смысл использовать Экстернализацию вместо сериализации (java.io.Externalizable). |
| Автор: COVD 22.1.2009, 19:01 |
| Возможно, для этого удобнее сериализовать в виде xml. Например, java.beans.XMLEncoder .. XMLDecoder . Если при десериализации обнаруживается , что сеттер отсутствует, то выдается сообщение и восстановление продолжается. Обьект должен быть бином. Инициировать новые поля надо самостоятельно. |