Изучаем Java: Сохранение объекта в файл. Сериализация |
Привет всем. Сегодня будет чисто техническая статья об одной из полезных функций языка Java.
Часто в программах возникает необходимость сохранять данные. В моем случае это чаще всего сохранение игры или координаты определенных обьектов сцены.
Можно действовать по старинке и реализовать сохранение в обычный текстовый файл. Но для этого вам прийдется писать "шифровщик " и дешифровщик", чтобы вся информация с ваших обьктов погла поместится в строчки текстового документа.
Подход не очень удобный и трудоемкий. На замену ему пришла сериализация. Возможно вы уже встречались с ней в языке C#, она там реализована очень похожим способом.
Вся фишка сериализации- в том что вы можеет сохранять обьекты любых класссов всего парой строчек кода. Считывание происходит так же.
Я сам уже давно пользуюсь данной функцией, но буквально вчера узнал ее некоторую особенность. Но для начала я покажу код самой сериализации.
Вот код сохранения в файл:
try{
FileOutputStream fos = new FileOutputStream("temp.txt");
ObjectOutputStream outStream = new ObjectOutputStream(fos);
MyClass testObject = new MyClass();
oos.writeObject(testObject);
outStream.flush();
outStream.close();
}catch(Exception e)
{
System.out.println("Error+e.getMessage());
}
MyClass testObject = new MyClass(); - здесь происходит создание обьекта вашего класса. Обычно обьекты создаются в другом месте. Это просто пример, чтобы было видно что сохраняются созданные вами данные.
Теперь код считывания:
try{ FileInputStream fis = new FileInputStream("temp.txt");
ObjectInputStream inputStream = new ObjectInputStream(fis);
MyClass testObject= (MyClass) inputStream .readObject();
inputStream.close
}catch(Exception e){
System.out.println("Error+e.getMessage());
}
Вот и все. Ваши данные теперь будут автоматически переводиться в байт-код и сохраняться в файл.
Теперь важно! Здесь многие допускают ошибки.
Чтобы обьект класса мог сохранится, нужно пометить этот клас вот так
import java.io.Serializable; // в области импорта, вначале программы
class MyClass implements Serializable{
}
Это говорит шифровщику, что класс можно сериализовать, иначе ничего не получится.
Поля, которые вы не хотите сохранять, нужно пометить как transient
Например,
transient public int number;
Теперь я расскажу об одной особенности, с которой вы наверняка столкнетесь.
Представим клас в вложенным в него еще одним классом.
class MyClass{
NewClass someObject=new NewClass();
class NewClass implements Serializable{
}
}
Так вот, если вы попытаетесь сериализовать обьект someObject, то ничего не получится. Механизм сериализации такой, что нельз сериализовать только вложенный класс. Неизбежно будут сохранятся и данные из вышестоящего класса MyClass. И нужно будет помечать MyClass как Serializable.
Это очень неудобно тогда, когда вам нужно сохранять один и тот же обьект, но при этом все остальные обьекты могут менятся, и вы меняете код своей программы. Тогда при добавление хоть одно поля в MyClass данные из файла не смогут считается) С этим я как раз и столкнулся.
Выход из этой ситуации простой. Нужно вынести внутренний класс NewClass наружу. В отдельный файл или просто рядом с MyClass.
Тогда у вас не возникнет никаких проблем. Вы сможете спокойно редактировать основной класс, при этом никак не влияя на процесс сериализации.
Надеюсь мой опыт кому- нибудь пригодится. Если будет,что интересное, то напишу еще. Планируется целый цикл статей о том как создать на Java полноценную 2д игру от начала и до Инсталлера)))
Всем удачи. Пока
Комментировать | « Пред. запись — К дневнику — След. запись » | Страницы: [1] [Новые] |