如何序列化对象并将其保存到 Android 中的文件中?
Posted
技术标签:
【中文标题】如何序列化对象并将其保存到 Android 中的文件中?【英文标题】:How do I serialize an object and save it to a file in Android? 【发布时间】:2011-05-06 08:20:38 【问题描述】:假设我有一些简单的类,一旦它被实例化为一个对象,我希望能够将其内容序列化到一个文件中,并通过稍后加载该文件来检索它......我不知道在哪里从这里开始,我需要做什么才能将此对象序列化为文件?
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? */
这可能是世界上最简单的问题,因为在 .NET 中这是一个非常简单的任务,但在 android 中我还很新,所以我完全迷路了。
【问题讨论】:
【参考方案1】:保存(无异常处理代码):
FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this);
os.close();
fos.close();
正在加载(无异常处理代码):
FileInputStream fis = context.openFileInput(fileName);
ObjectInputStream is = new ObjectInputStream(fis);
SimpleClass simpleClass = (SimpleClass) is.readObject();
is.close();
fis.close();
【讨论】:
非常有用。您能否解释一下我们是否必须将类序列化为目标文件。 如果您使用 Serializable 接口,此功能会隐式添加到您的类中。如果你想要的只是简单的对象序列化,那就是我会使用的。它也非常容易实现。 developer.android.com/reference/java/io/Serializable.html +1,要保存多个对象,需要技巧:***.com/a/1195078/1321401 是否也应该调用 fos.close() 和 fis.close() ? 我推荐Paper。它使用 Kryo 序列化,比普通的 Java 序列化要快得多。【参考方案2】:我已经尝试了这 2 个选项(读/写),使用普通对象、对象数组(150 个对象)、地图:
选项1:
FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this);
os.close();
选项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();
选项 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);
【讨论】:
为什么说选项 2 更快?也许是因为 SharedPreferences 保存在内存中,而您测量的时间不包括将其保存到文件系统?我问这个是因为我想序列化到对象流必须比 JSON 字符串更有效。 我也不知道为什么,但是官方序列化kotlin文档中似乎也使用了Json。为什么 JSON 是默认的...【参考方案3】:我刚刚创建了一个类来处理泛型,因此它可以用于所有可序列化的对象类型:
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);
【讨论】:
【参考方案4】:带有错误处理和添加的文件流关闭的完整代码。将它添加到您希望能够序列化和反序列化的类中。在我的例子中,类名是CreateResumeForm
。您应该将其更改为您自己的类名。 Android
interface 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;
在你的Activity
中这样使用它:
form = CreateResumeForm.readFromFile(this);
【讨论】:
【参考方案5】:我使用 SharePrefrences:
package myapps.serializedemo;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Create the SharedPreferences
SharedPreferences sharedPreferences = this.getSharedPreferences("myapps.serilizerdemo", Context.MODE_PRIVATE);
ArrayList<String> friends = new ArrayList<>();
friends.add("Jack");
friends.add("Joe");
try
//Write / Serialize
sharedPreferences.edit().putString("friends",
ObjectSerializer.serialize(friends)).apply();
catch (IOException e)
e.printStackTrace();
//READ BACK
ArrayList<String> newFriends = new ArrayList<>();
try
newFriends = (ArrayList<String>) ObjectSerializer.deserialize(
sharedPreferences.getString("friends", ObjectSerializer.serialize(new ArrayList<String>())));
catch (IOException e)
e.printStackTrace();
Log.i("***NewFriends", newFriends.toString());
【讨论】:
【参考方案6】:您必须在您的程序中添加一个 ObjectSerialization 类,以下可能会起作用
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectSerializer
public static String serialize(Serializable obj) throws IOException
if (obj == null) return "";
try
ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
ObjectOutputStream objStream = new ObjectOutputStream(serialObj);
objStream.writeObject(obj);
objStream.close();
return encodeBytes(serialObj.toByteArray());
catch (Exception e)
throw new RuntimeException(e);
public static Object deserialize(String str) throws IOException
if (str == null || str.length() == 0) return null;
try
ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
ObjectInputStream objStream = new ObjectInputStream(serialObj);
return objStream.readObject();
catch (Exception e)
throw new RuntimeException(e);
public static String encodeBytes(byte[] bytes)
StringBuffer strBuf = new StringBuffer();
for (int i = 0; i < bytes.length; i++)
strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
return strBuf.toString();
public static byte[] decodeBytes(String str)
byte[] bytes = new byte[str.length() / 2];
for (int i = 0; i < str.length(); i+=2)
char c = str.charAt(i);
bytes[i/2] = (byte) ((c - 'a') << 4);
c = str.charAt(i+1);
bytes[i/2] += (c - 'a');
return bytes;
如果您使用 SharedPreferences 存储数组而不是使用以下内容:-
SharedPreferences sharedPreferences = this.getSharedPreferences(getPackageName(),MODE_PRIVATE);
序列化:-
sharedPreferences.putString("name",ObjectSerializer.serialize(array));
反序列化:-
newarray = (CAST_IT_TO_PROPER_TYPE) ObjectSerializer.deSerialize(sharedPreferences.getString(name),null);
【讨论】:
以上是关于如何序列化对象并将其保存到 Android 中的文件中?的主要内容,如果未能解决你的问题,请参考以下文章
如何拆分/解析 JSON 数据并将其保存到 SQL 服务器中?
如何保存从Kinect 2.0收集的Body数据并将其保存在JSON文件中?
自定义对象的 Android ArrayList - 保存到 SharedPreferences - 可序列化?
如何从服务器下载文件并将其保存在 Android SD 卡中的特定文件夹中?