【问题标题】:ObjectInputStream gives me an empty object (but the readed file is not empty)ObjectInputStream 给了我一个空对象(但读取的文件不是空的)
【发布时间】:2012-07-23 07:15:19
【问题描述】:

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

public class SaveState implements Serializable{
   public static ArrayList <String> favoriteBusStopNumbers = new ArrayList<String>();
   public static SaveState instance=new 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.instance);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

最后,我在我的应用程序的初始化中使用此方法来加载文件并用以前存储的数据填充我的 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 的磁盘空间。但是这里出了点问题,因为当我启动我的应用程序并加载数据时,我的 SaveState.instance 变量得到一个空的 ArrayList 字符串......然后¿代码有什么问题?

谢谢

【问题讨论】:

    标签: java android serialization objectoutputstream objectinputstream


    【解决方案1】:

    您的数组列表是静态的。静态变量与类相关联,而不与对象相关联。所以他们不会被序列化。

    如果你确实想序列化静态变量,你必须重写 readObject 和 writeObject。

    这里有一些附加信息——http://java.sun.com/developer/technicalArticles/Programming/serialization/

    这里最好的解决方案是重新考虑你的数据结构,如果 arraylist 保存对象的状态,则使它成为非静态的。

    编辑:或者,您可以只序列化数组列表(如下@Ted 建议的那样)

    【讨论】:

    • 我没有使用static,但我的arraylist对象在readObject()之后是空白的。关于这个问题的任何线索?
    【解决方案2】:

    问题是标记为静态的变量不会被序列化,除非你实现

    private void readObject(ObjectInputStream ois){}  
    

    private void writeObject(ObjectOutputStream oos){}
    

    ObjectOutputStream - JavaDoc:

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

    【讨论】:

      【解决方案3】:

      由于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 字段。

      【讨论】:

        猜你喜欢
        • 2012-06-08
        • 2013-11-09
        • 2018-01-10
        • 2018-08-25
        • 2018-10-10
        • 2019-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多