Как прочитать и переписать одноэлементный объект из файла? - PullRequest
0 голосов
/ 02 декабря 2011
public class Storage implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public static List<Message> MessageList = Collections.synchronizedList(new ArrayList<Message>()); //Fail safe if multiple threads modify them.
    public static List<Group> GroupList = Collections.synchronizedList(new ArrayList<Group>());

    protected Storage() {
        super();
    }

    static private Storage _instance = null;

    //initialized: Storage.instance();
    static public Storage instance() {
        if(_instance == null) {
            _instance = new Storage();
        }
     return _instance;
    }



}

У меня есть высший класс, который создает один объект.Я хочу сохранить этот объект с его списками в файл.Затем, когда мое приложение запускается и я создаю экземпляр хранилища, я хочу, чтобы оно прочитало файл, и если оно пустое, создайте новое хранилище, но если его нет, то прочитайте предыдущий экземпляр хранилища и создайте его на основе старого.В основном это означает, что я хочу, чтобы содержимое GroupList и MessageList было постоянным.

РЕДАКТИРОВАТЬ: , потому что я не дал достаточно ясного объяснения.

Где я могу разместитькод, необходимый для проверки и чтения предыдущего экземпляра этого класса в?Я предполагаю в конструкторе, но тогда мои списки также получат значения другого объекта?Я не знаю, где и как это кодировать.

EDIT2: решение для вставки.

public class Storage implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public static List<Message> MessageList = Collections.synchronizedList(new ArrayList<Message>()); //Fail safe if multiple threads modify them.
    public static List<Group> GroupList = Collections.synchronizedList(new ArrayList<Group>());

    protected Storage() {
        super();
    }

    static private Storage _instance = null;

    //initialized: Storage.instance();
    public static synchronized Storage instance(){
        initialize();
        if(_instance == null) {
            _instance = new Storage();
        }
        return _instance;
    }

    public static synchronized void persist(){
        FileOutputStream fos = null;
        ObjectOutputStream out = null;
        try{
            fos = new FileOutputStream("Storage.txt");
            out = new ObjectOutputStream(fos);
            out.writeObject(instance());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



    protected static synchronized void initialize(){
        FileInputStream fis = null;
        ObjectInputStream in = null;
        try{
            fis = new FileInputStream("Storage.txt");
            in = new ObjectInputStream(fis);
            _instance = (Storage)in.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (OptionalDataException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static synchronized void addElement(Message message){
        if(!MessageList.contains(message)){
            MessageList.add(message);
            persist();
            Log.i("STORAGE-addElement", "Added: " + message);
        }
    }

    public static synchronized void addElement(Group group){
        if(!GroupList.contains(group)){
            GroupList.add(group);
            persist();
            Log.i("STORAGE-addElement", "Added: " + group);
        }
    }

    public static synchronized void removeElement(Message message){
        if(!MessageList.contains(message)){
            MessageList.remove(message);
            persist();
            Log.i("STORAGE-removeElement", "Removed: " + message);
        }
    }

    public static synchronized void removeElement(Group group){
        if(!GroupList.contains(group)){
            GroupList.remove(group);
            persist();
            Log.i("STORAGE-removeElement", "Removed: " + group);
        }
    }

    public static synchronized void wipeAll(){
        MessageList.clear();
        GroupList.clear();
        persist();
        Log.i("STORAGE-wipeAll", "Wiped all data");
    }

}

Спасибо за вашу помощь!:)

Ответы [ 6 ]

2 голосов
/ 02 декабря 2011

Хорошее описание API сериализации Java здесь:

http://java.sun.com/developer/technicalArticles/Programming/serialization/

Короткая версия - вам, вероятно, нужно добавить следующие два метода, чтобы настроить способ написания вашего объекта. Обратите внимание, что они не переопределяют любой метод суперкласса - просто добавьте их с этими точными сигнатурами.

Убедитесь, что ваши объекты Message и Group также сериализуются.

Затем вы создадите ObjectOuputStream и вызовете его метод writeObject для записи вашего объекта в файл.

Методы, добавляемые в ваш сериализуемый класс:

private void writeObject(ObjectOutputStream out) throws IOException

и

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
2 голосов
/ 02 декабря 2011

Вы можете добавить следующие методы в свой объект Storage:

public void persist() throws IOException{

  FileOutputStream fos = null;
  ObjectOutputStream out = null;
  try{
   fos = new FileOutputStream(FILE_NAME); //assumes filename is a constant you've defined
   out = new ObjectOutputStream(fos);
   out.writeObject(time);
  }finally{
    out.close();
  }
}



protected static void initialize() throws IOException{
   FileInputStream fis = null;
   ObjectInputStream in = null;
   try{
     fis = new FileInputStream(FILE_NAME);
     in = new ObjectInputStream(fis);
     instance  = (PersistentTime)in.readObject();
   }finally{
     in.close();
   }
}

Вы можете вызвать initialize() из вашего статического instance метода вместо прямого вызова конструктора.

2 голосов
/ 02 декабря 2011

Это можно сделать, прочитав объект в методе main вашего приложения и сохранив его снова в методе main рядом с точкой выключения.Может быть, я что-то упустил.

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

Все вышеперечисленное - и измените эти списки, чтобы они тоже не были статичными!

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

Очевидно, что вам нужно хранить сериализованный синглтон в файловой системе, поэтому вам потребуется каноническое расположение, например, параметр конфигурации для имени файла.

Тогда метод доступа к экземпляру эффективно отвечает за маршалинг / демаршаллинг персистентного экземпляра. Это легкая часть. (Для надежной системы существует небольшая группа червей: вам нужно убедиться, что никакой другой процесс никогда не записывает в этот файл, например, если другой экземпляр JVM запускается и использует тот же класс синглтона. Опять же: имя сериализованного файла простой механизм для решения этой проблемы.

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

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

Я предполагаю, что в вашем реальном классе хранения есть код, который устанавливает данные члена для объекта Storage.Учитывая это, я бы порекомендовал что-то вроде:

static public Storage instance() {
    if(_instance != null) {
        return _instance;
    }

    _instance = new Storage();

    if (file.exists()) {
         deserialize_Storage_data_from_file();
    }

    return _instance;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...