如何序列化对象并将其保存到Android中的文件?

Ben*_*esh 124 file-io serialization android

假设我有一些简单的类,一旦它被实例化为一个对象,我希望能够将其内容序列化为一个文件,并通过稍后加载该文件来检索它......我不知道从哪里开始,如何将此对象序列化为文件需要做什么?

public class SimpleClass {
   public string name;
   public int id;
   public void save() {
       /* wtf do I do here? */
   }
   public static SimpleClass load(String file) {
       /* what about here? */
   }
}
Run Code Online (Sandbox Code Playgroud)

这可能是世界上最简单的问题,因为这在.NET中是一个非常简单的任务,但在Android中我很新,所以我完全迷失了.

Ral*_*kie 242

保存(没有异常处理代码):

FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this);
os.close();
fos.close();
Run Code Online (Sandbox Code Playgroud)

加载(没有异常处理代码):

FileInputStream fis = context.openFileInput(fileName);
ObjectInputStream is = new ObjectInputStream(fis);
SimpleClass simpleClass = (SimpleClass) is.readObject();
is.close();
fis.close();
Run Code Online (Sandbox Code Playgroud)

  • +1,对于保存多个对象,需要技巧:http://stackoverflow.com/a/1195078/1321401 (6认同)
  • 如果使用Serializable接口,则会将此功能隐式添加到您的类中.如果你想要的只是简单的对象序列化,那就是我会用的.它也非常容易实现.http://developer.android.com/reference/java/io/Serializable.html (4认同)
  • 是否应该调用fos.close()和fis.close()? (2认同)

sur*_*sea 31

我试过这两个选项(读/写),普通对象,对象数组(150个对象),Map:

选项1:

FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this);
os.close();
Run Code Online (Sandbox Code Playgroud)

选项2:

SharedPreferences mPrefs=app.getSharedPreferences(app.getApplicationInfo().name, Context.MODE_PRIVATE);
SharedPreferences.Editor ed=mPrefs.edit();
Gson gson = new Gson(); 
ed.putString("myObjectKey", gson.toJson(objectToSave));
ed.commit();
Run Code Online (Sandbox Code Playgroud)

选项2比选项1快两倍

选项2的不便之处在于您必须为阅读制作特定代码:

Gson gson = new Gson();
JsonParser parser=new JsonParser();
//object arr example
JsonArray arr=parser.parse(mPrefs.getString("myArrKey", null)).getAsJsonArray();
events=new Event[arr.size()];
int i=0;
for (JsonElement jsonElement : arr)
    events[i++]=gson.fromJson(jsonElement, Event.class);
//Object example
pagination=gson.fromJson(parser.parse(jsonPagination).getAsJsonObject(), Pagination.class);
Run Code Online (Sandbox Code Playgroud)

  • 你为什么说选项2更快?也许是因为SharedPreferences保存在内存中并且您测量的时间不包括将其保存到文件系统中?我问这个是因为我认为序列化到对象流必须比JSON字符串更有效. (3认同)

San*_*ado 9

我只是用Generics创建了一个类来处理它,所以它可以用于所有可序列化的对象类型:

public class SerializableManager {

    /**
     * Saves a serializable object.
     *
     * @param context The application context.
     * @param objectToSave The object to save.
     * @param fileName The name of the file.
     * @param <T> The type of the object.
     */

    public static <T extends Serializable> void saveSerializable(Context context, T objectToSave, String fileName) {
        try {
            FileOutputStream fileOutputStream = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

            objectOutputStream.writeObject(objectToSave);

            objectOutputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Loads a serializable object.
     *
     * @param context The application context.
     * @param fileName The filename.
     * @param <T> The object type.
     *
     * @return the serializable object.
     */

    public static<T extends Serializable> T readSerializable(Context context, String fileName) {
        T objectToReturn = null;

        try {
            FileInputStream fileInputStream = context.openFileInput(fileName);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            objectToReturn = (T) objectInputStream.readObject();

            objectInputStream.close();
            fileInputStream.close();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        return objectToReturn;
    }

    /**
     * Removes a specified file.
     *
     * @param context The application context.
     * @param filename The name of the file.
     */

    public static void removeSerializable(Context context, String filename) {
        context.deleteFile(filename);
    }

}
Run Code Online (Sandbox Code Playgroud)


wzb*_*zon 7

完成代码并关闭错误处理和添加的文件流.将它添加到您希望能够序列化和反序列化的类中.在我的情况下,类名是CreateResumeForm.您应该将其更改为您自己的类名.Androidinterface Serializable不足以将对象保存到文件中,它只创建流.

// Constant with a file name
public static String fileName = "createResumeForm.ser";

// Serializes an object and saves it to a file
public void saveToFile(Context context) {
    try {
        FileOutputStream fileOutputStream = context.openFileOutput(fileName, Context.MODE_PRIVATE);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(this);
        objectOutputStream.close();
        fileOutputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


// Creates an object by reading it from a file
public static CreateResumeForm readFromFile(Context context) {
    CreateResumeForm createResumeForm = null;
    try {
        FileInputStream fileInputStream = context.openFileInput(fileName);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        createResumeForm = (CreateResumeForm) objectInputStream.readObject();
        objectInputStream.close();
        fileInputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return createResumeForm;
}
Run Code Online (Sandbox Code Playgroud)

在你的使用中使用它Activity:

form = CreateResumeForm.readFromFile(this);
Run Code Online (Sandbox Code Playgroud)