有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从文件中读取和重写单例对象?

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) 个答案

  1. # 1 楼答案

    可以通过在应用程序的main方法中读取对象并在靠近关闭点的main方法中再次保存来完成。也许我错过了什么

  2. # 2 楼答案

    以上所有内容-并将这些列表更改为非静态

  3. # 3 楼答案

    我假设在您的实际存储类中有代码为存储对象设置成员数据。有鉴于此,我将推荐以下内容:

    static public Storage instance() {
        if(_instance != null) {
            return _instance;
        }
    
        _instance = new Storage();
    
        if (file.exists()) {
             deserialize_Storage_data_from_file();
        }
    
        return _instance;
    }
    
  4. # 4 楼答案

    这里对Java序列化api有一个很好的描述:

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

    简短的版本是,您可能需要添加以下两种方法来自定义对象的编写方式。请注意,这些不会覆盖任何超类方法——只需使用这些精确的签名添加它们

    确保消息和组对象也可序列化

    然后创建一个ObjectOuputStream并调用其writeObject方法将对象写入文件

    要添加到可序列化类的方法:

    private void writeObject(ObjectOutputStream out) throws IOException
    

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
    
  5. # 5 楼答案

    您可以向存储对象添加以下方法:

    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();
       }
    }
    

    您可以从静态instance方法调用initialize(),而不是直接调用构造函数

  6. # 6 楼答案

    显然,您需要将序列化的单例存储在文件系统中,因此需要一个规范位置,例如,文件名的配置参数

    然后,实例访问器方法有效地负责对持久实例进行编组/解编组。这是最简单的部分。(对于一个健壮的系统来说,有一小罐蠕虫:您需要确保没有其他进程写入此文件,例如,如果出现另一个JVM实例并使用相同的单例类。同样,序列化文件的名称是解决此问题的简单机制

    在操作上,对实例(在mem中)的任何更改都需要与持久化表单同步,例如,一致性需求将需要某种事务语义。最简单(但效率最低)的方法是,在单例实例上的每个变异操作上,例如在修改列表内容时,将实例刷新到序列化文件中