如何使用Serializable将一个类对象存储到内部存储器中?

3
我需要将这个对象存储到手机的内部存储器中,并且我在清单文件中设置了<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"></uses-permission>。该对象本身具有两个静态方法,用于从内部存储器中存储和重新加载它:
public class SaveState implements Serializable {
static public List<FullMagazine> fms = new ArrayList<FullMagazine>();
static SaveState instance=null;

public static SaveState getInstance(){      
    if( instance == null )
        instance = new SaveState();     
    return instance;
}

public static void saveData(SaveState instance){
    ObjectOutput out;
    try {
        out = new ObjectOutputStream(new FileOutputStream("appSaveState.data"));        
        out.writeObject(instance);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

public static SaveState loadData(){
    ObjectInput in;
    SaveState ss=null;
    try {
        in = new ObjectInputStream(new FileInputStream("appSaveState.data"));       
        ss=(SaveState) in.readObject();
        in.close();
    } catch (Exception e) {e.printStackTrace();}
    return ss;
}
}

我正在尝试使用以下代码在我的活动中储存并重新打开它:

```

            SaveState.fms.add(fm);
            SaveState.saveData(SaveState.getInstance());                
            SaveState sv = SaveState.loadData();

但它并没有起作用,它没有存储该对象,当然也没有读取该对象。在存储和读取对象时,我得到了这两个异常:

    03-23 09:18:16.702: WARN/System.err(9060): java.io.FileNotFoundException: /appSaveState.data (Read-only file system)
03-23 09:18:16.702: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
03-23 09:18:16.702: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:97)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:168)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:147)
03-23 09:18:16.702: WARN/System.err(9060):     at com.Magazine.SaveState.saveData(SaveState.java:35)
03-23 09:18:16.702: WARN/System.err(9060):     at com.Magazine.MainMenu$DownloadThread.run(MainMenu.java:807)
03-23 09:18:16.709: WARN/System.err(9060): java.io.FileNotFoundException: /appSaveState.data (No such file or directory)
03-23 09:18:16.709: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
03-23 09:18:16.709: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
03-23 09:18:16.709: WARN/System.err(9060):     at java.io.FileInputStream.<init>(FileInputStream.java:82)
03-23 09:18:16.709: WARN/System.err(9060):     at java.io.FileInputStream.<init>(FileInputStream.java:134)
03-23 09:18:16.709: WARN/System.err(9060):     at com.Magazine.SaveState.loadData(SaveState.java:46)
03-23 09:18:16.709: WARN/System.err(9060):     at com.Magazine.MainMenu$DownloadThread.run(MainMenu.java:809)

代码出了什么问题吗?
谢谢。

问题在于你试图写入 Android 中只读的 / 目录。 - Menachem Hornbacher
静态列表FullMagazine中使用的类是否也实现了Serializable接口? - Sharp Edge
3个回答

6

修改这个内容

out = new ObjectOutputStream(new FileOutputStream("appSaveState.data"));

使用

   File outFile = new File(Environment.getExternalStorageDirectory(), "appSaveState.data");
   out = new ObjectOutputStream(new FileOutputStream(outFile)); 

正如@e-x所指出的那样,清除应用数据或卸载应用程序时文件将不会被删除。

如果手机没有安装SD卡,会发生什么?我正在尝试将其存储在内部存储器上,因为我必须在所有手机上存储这些数据,包括没有SD卡的手机。 - NullPointerException
1
如果您正在提到没有SD卡支持的手机(如三星Nexus S),则Enviromenet.getExternalStorageDirectory()将返回指向手机内部存储档案的路径。 - Blackbelt
1
我认为值得一提的是,如果手机有SD卡,则在清除应用程序数据时文件将保留。 - E_X
@E_X,我更新了答案,感谢你的贡献。 - Blackbelt

2

即使您获得了权限,也不允许直接写入内部存储。请尝试使用外部SD卡或缓存文件夹


缓存文件夹中的数据在应用程序从手机上卸载之前是持久的吗?请告诉我如何使用缓存文件夹来实现,我应该在我的代码中做出哪些更改? - NullPointerException
文件 cacheFile = new File(activity.getCacheDir(), "appSaveState.data"); - 像以前一样写入该文件。 - Tim
2
缓存文件夹在空闲空间越来越少时,很容易被操作系统删除! - Dumbo

1
这是我基于此帖子和this的方法:
我在我的User类中编写了这个。
private static File mFolder;
public void saveData(Activity pContext) {
    //this could be initialized once onstart up
    if(mFolder == null){
        mFolder = pContext.getExternalFilesDir(null);
    }
    this.save();
    ObjectOutput out;
    try {
        File outFile = new File(mFolder,
                "someRandom.data");
        out = new ObjectOutputStream(new FileOutputStream(outFile));
        out.writeObject(this);
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static User loadData(Context pContext) {
    if(mFolder == null){
        mFolder = pContext.getExternalFilesDir(null);
    }
    ObjectInput in;
    User lUser = null;
    try {
        FileInputStream fileIn = new FileInputStream(mFolder.getPath() + File.separator + "someRandom.data");
        in = new ObjectInputStream(fileIn);
        lUser = (User) in.readObject();
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (lUser != null) {
        lUser.save();
        Log.d("current User: ", lUser.nickname);
    } else {
        Log.d("current User: ", "null");
    }
    return lUser;
}

然后从我的活动中调用:
mUser = User.loadData(mSelf);

或者

mUser = User.loadData(this);

mSelf将是我存储的一个实例

希望这有所帮助 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接