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");
}
}
谢谢你的帮助!:)
# 1 楼答案
可以通过在应用程序的main方法中读取对象并在靠近关闭点的main方法中再次保存来完成。也许我错过了什么
# 2 楼答案
以上所有内容-并将这些列表更改为非静态
# 3 楼答案
我假设在您的实际存储类中有代码为存储对象设置成员数据。有鉴于此,我将推荐以下内容:
# 4 楼答案
这里对Java序列化api有一个很好的描述:
http://java.sun.com/developer/technicalArticles/Programming/serialization/
简短的版本是,您可能需要添加以下两种方法来自定义对象的编写方式。请注意,这些不会覆盖任何超类方法——只需使用这些精确的签名添加它们
确保消息和组对象也可序列化
然后创建一个
ObjectOuputStream
并调用其writeObject方法将对象写入文件要添加到可序列化类的方法:
及
# 5 楼答案
您可以向存储对象添加以下方法:
您可以从静态
instance
方法调用initialize()
,而不是直接调用构造函数# 6 楼答案
显然,您需要将序列化的单例存储在文件系统中,因此需要一个规范位置,例如,文件名的配置参数
然后,实例访问器方法有效地负责对持久实例进行编组/解编组。这是最简单的部分。(对于一个健壮的系统来说,有一小罐蠕虫:您需要确保没有其他进程写入此文件,例如,如果出现另一个JVM实例并使用相同的单例类。同样,序列化文件的名称是解决此问题的简单机制
在操作上,对实例(在mem中)的任何更改都需要与持久化表单同步,例如,一致性需求将需要某种事务语义。最简单(但效率最低)的方法是,在单例实例上的每个变异操作上,例如在修改列表内容时,将实例刷新到序列化文件中