How to Serialize an Object and Save It to a File in Android

How do I serialize an object and save it to a file in Android?

Saving (w/o exception handling code):

FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(this);
os.close();
fos.close();

Loading (w/o exception handling code):

FileInputStream fis = context.openFileInput(fileName);
ObjectInputStream is = new ObjectInputStream(fis);
SimpleClass simpleClass = (SimpleClass) is.readObject();
is.close();
fis.close();

read/write an object to file

You don't need to use the 'byte array' approach. There is an easy way to (de)serialize objects.

EDIT: here's the long version of code

Read:

public void read(){
ObjectInputStream input;
String filename = "testFilemost.srl";

try {
input = new ObjectInputStream(new FileInputStream(new File(new File(getFilesDir(),"")+File.separator+filename)));
Person myPersonObject = (Person) input.readObject();
Log.v("serialization","Person a="+myPersonObject.getA());
input.close();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}

Write:

public void write(){
Person myPersonObject = new Person();
myPersonObject.setA(432);
String filename = "testFilemost.srl";
ObjectOutput out = null;

try {
out = new ObjectOutputStream(new FileOutputStream(new File(getFilesDir(),"")+File.separator+filename));
out.writeObject(myPersonObject);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

Person class:

public class Person implements Serializable {
private static final long serialVersionUID = -29238982928391L;
int a;

public int getA(){
return a;
}

public void setA(int newA){
a = newA;
}
}

Writing an serialized object to a file

First of all we can try to write in public directory so results can be easily checked with any file manager app.

Before writing to the filesystem ensure that AndroidManifest.xml contains two permission requests:

<manifest ...>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

...
</manifest>

We can proceed to writing files if your device or emulator/VM running Android 5 or below. If it is not, please take a look at the part of android developer documentation about requesting permissions at runtime.

Here's some code that will give you writable directory with 95% probability:

File destination = new File(Environment.getExternalStorageDirectory(), "My Cool Folder");
destination.mkdirs();

So now you can try to write a file there

fileOutputStream = new FileOutputStream(new File(destination, "outgoings.tmp"));
//write there anything you want

Reading and writing a serialized object in android

First of all make sure that you have permission to write to the external storage.

as,

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

You can use,

  public void addCurrentList() throws Exception{

String pathToAppFolder = getExternalFilesDir(null).getAbsolutePath();
String filePath = pathToAppFolder +File.seperator + "list.ser";
try {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(filePath));
os.writeObject(list);
os.close();
}
catch (Exception e) {
System.out.println("");
}
}

and the use create a file path from that as,

String filePath = pathToAppFolder +File.seperator + "Test.text";

and then where ever you want to read this file again, you can recreate the path. Because you have access to the context from the android code

EDIT

You can not access the context as you do in your code. You can do it in your onCreate method. I have added only the necessary parts.

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

pathToAppFolder = getExternalFilesDir(null).getAbsolutePath();
filePath = pathToAppFolder + File.separator + "list.ser";
//create the list

Oh my god, I had to go into great lengths to answer your question. Here it is, Your List class is not an Activity in your application. It is just a class. So I suggest you to remove those inheritance first. remove this extends Activity. And I suggest you to change the List class name to something else. Because, List is a defined keyword and its not a best practice to do so.

Change the method in List Activity as below.

    public void addCurrentList(String filePath) throws Exception

try {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(filePath));



os.writeObject(list);
os.close();
}
catch (Exception e) {

System.out.println(e.getMessage());


}
}

public void record(String filePath) {

try {

ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath));
ArrayList<Item> list2 = (ArrayList<Item>) in.readObject();
System.out.println(list2);
list = list2;

in.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}

In your MainActivity, onDestroy Method,
change the code to,

tester.addCurrentList(filePath);

Serialize an Object and Save in Sqllite DB

Made some changes in your code as below.

First implement Serializable interface in class Employee.java

public void serailize() {
Employee e = new Employee();
e.setName("Reyan Ali");
e.setAddress("Phokka Kuan, Ambehta Peer");
e.setSSN(11122333);
e.setNumber(101);
try {
ObjectOutputStream out = new ObjectOutputStream(openFileOutput(
"employee.ser", MODE_PRIVATE));
out.writeObject(e);
out.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
} catch (IOException i) {
i.printStackTrace();
}
}

public void deSerailize() {
Employee e = null;
try {
ObjectInputStream in = new ObjectInputStream(
openFileInput("employee.ser"));
e = (Employee) in.readObject();
in.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Serialized class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}

OpenFileInput() and openFileOutPut() are the application private files.

I think it is good to store serialized data in files.

How to write serializable object to String without writing to file?

This would be one way:

try 
{
// To String
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(object1);
String serializedObject1 = bos.toString();
os.close();

// To Object
ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject1.getBytes());
ObjectInputStream oInputStream = new ObjectInputStream(bis);
YourObject restoredObject1 = (YourObject) oInputStream.readObject();

oInputStream.close();
} catch(Exception ex) {
ex.printStackTrace();
}

I would prefer the Base64 way though.

This would be an example of encoding:

private static String serializableToString( Serializable o ) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
return Base64.getEncoder().encodeToString(baos.toByteArray());
}

And this is an example of decoding:

 private static Object objectFromString(String s) throws IOException, ClassNotFoundException 
{
byte [] data = Base64.getDecoder().decode(s);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(data));
Object o = ois.readObject();
ois.close();
return o;
}


Related Topics



Leave a reply



Submit