ObjectInputStream给了我一个空对象(但是readed文件不为空)

时间:2012-07-24 21:50:31

标签: java android serialization objectoutputstream objectinputstream

我有这个可序列化的类,我用它来存储一个二进制文件的字符串ArrayList。

public class SaveState implements Serializable{
   public static ArrayList <String> favoriteBusStopNumbers = new ArrayList<String>();
   public static SaveState instance=new SaveState();
}

一旦这个数组已经满了我必须存储的数据,我正在使用这个方法来存储带有arrayList字符串的实例:

public static void saveData(){
    ObjectOutput out;
    try {
        //primero comprobamos si existe el directorio, y si no, lo creamos.
        File folder = new File(Environment.getExternalStorageDirectory() + DIRECTORY_NAME);
        if(!folder.exists())
            folder.mkdirs();

        File outFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        out = new ObjectOutputStream(new FileOutputStream(outFile)); 
        out.writeObject(SaveState.instance);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

最后,我在我的app的init上使用此方法加载文件并使用以前存储的数据填充我的SaveState.instance变量:

public static void loadData(){
    ObjectInput in;
    try {
        File inFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        in = new ObjectInputStream(new FileInputStream(inFile));        
        SaveState.instance=(SaveState) in.readObject();
        in.close();
    } catch (Exception e) {e.printStackTrace();}
}

当我保存数据时,正在使用对象填充数据正确创建文件,我知道它因为文件的磁盘空间超过0KB。但是这里出现了问题,因为当我启动我的app并加载数据时,我的SaveState.instance变量获取一个空的ArrayList字符串.......然后¿代码中出了什么问题?

由于

3 个答案:

答案 0 :(得分:6)

你的arraylist是静态的。静态变量与类关联,而不与对象关联。所以他们没有被序列化。

如果确实要序列化静态变量,则必须覆盖readObject和writeObject。

以下是一些其他信息 - http://java.sun.com/developer/technicalArticles/Programming/serialization/

此处的最佳解决方案是重新考虑您的数据结构,并在保存对象状态时使arraylist非静态。

编辑:或者,你可以序列化arraylist(正如@Ted建议的那样)

答案 1 :(得分:3)

问题是标记为static的变量除了实现

外不会被序列化
private void readObject(ObjectInputStream ois){}  

private void writeObject(ObjectOutputStream oos){}

ObjectOutputStream - JavaDoc:

  

对象的默认序列化机制会写入类   对象,类签名和所有非瞬态的值   和非静态字段。

答案 2 :(得分:1)

由于SaveState中保存的唯一数据是静态数组,因此只需序列化和反序列化数组就可以获得更多成功:

public static void saveData(){
    ObjectOutput out;
    try {
        //primero comprobamos si existe el directorio, y si no, lo creamos.
        File folder = new File(Environment.getExternalStorageDirectory() + DIRECTORY_NAME);
        if(!folder.exists())
            folder.mkdirs();

        File outFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        out = new ObjectOutputStream(new FileOutputStream(outFile)); 
        out.writeObject(SaveState.favoriteBusStopNumbers);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

@SuppressWarnings("unchecked")
public static void loadData(){
    ObjectInput in;
    try {
        File inFile = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME+"appSaveState.data");
        in = new ObjectInputStream(new FileInputStream(inFile));
        SaveState.favoriteBusStopNumbers=(ArrayList<String>) in.readObject();
        in.close();
    } catch (Exception e) {e.printStackTrace();}
}

(您需要禁止有关强制转换为泛型类型的警告。)

您根本不需要SaveState.instance字段。