I couldn't find a good example, so after some fighting with writing non-serializable object to file in Android, I decided to show you my solution. Could you tell me if it is OK or how could it be improved?
This class is used to store information in a file. writeObject
and readObject
methods were created, because android.graphics.Point
is not serializable. This is the reason why strokes
was declared as transient. To make sure that we are able to overwrite file, we need to create our own ObjectOutputStream
, which overrides writeStreamHeader
, so the second header will not be appended to our file. We check if the file size is greater that zero, and according to this we create our OutputStream
.
In general, what I understand is that to write a non-serializable object to file we need to make it transient and define our readObject
and writeObject
methods. To overwrite a file we need to make our own ObjectOutputStream
.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import android.graphics.Point;
import android.os.Environment;
public class LogInfo implements Serializable{
private static final long serialVersionUID = 710487907869630527L;
transient public ArrayList<Point[][]> strokes;
public LogInfo()
{
strokes = new ArrayList<Point[][]>();
}
private void writeObject(ObjectOutputStream stream) throws IOException
{
stream.defaultWriteObject();
stream.writeInt(strokes.size());
Point[][] pointsArray = null;
for (int i = 0; i < strokes.size(); i++)
{
pointsArray = ((Point[][])strokes.get(i));
stream.writeInt(pointsArray.length);
for (int j = 0; j < pointsArray.length; j++)
{
stream.writeInt(pointsArray[j].length);
for (int k = 0; k < pointsArray[j].length; k++)
{
stream.writeInt(pointsArray[j][k].x);
stream.writeInt(pointsArray[j][k].y);
}
}
}
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException, ClassCastException
{
stream.defaultReadObject();
strokes = new ArrayList<Point[][]>();
int strokesSize = stream.readInt();
for (int i = 0; i < strokesSize; i++)
{
int arrayXSize = stream.readInt();
Point[][] points = new Point[arrayXSize][];
for (int j = 0; j < arrayXSize; j++)
{
int arrayYSize = stream.readInt();
points[j] = new Point[arrayYSize];
for (int k = 0; k < arrayYSize; k++)
points[j][k] = new Point(stream.readInt(), stream.readInt());
}
strokes.add(points);
}
}
public void writeLog()
{
File file = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), "data.log");
FileOutputStream fos;
try {
fos = new FileOutputStream(file, true);
ObjectOutputStream writer;
if(file.length() > 0)
{
writer = new MyObjectOutputStream(fos);
}
else
{
writer = new ObjectOutputStream(fos);
}
writer.writeObject(this);
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ArrayList<LogInfo> readLog()
{
ArrayList<LogInfo> logInfoArray = new ArrayList<LogInfo>();
try{
File file = new File (Environment.getExternalStorageDirectory().getAbsolutePath(), "data.log");
FileInputStream fis = new FileInputStream(file);
ObjectInputStream reader = new ObjectInputStream(fis);
while (file.canRead())
{
logInfoArray.add((LogInfo) reader.readObject());
}
reader.close();
} catch (Exception e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
return logInfoArray;
}
}
class MyObjectOutputStream extends ObjectOutputStream {
public MyObjectOutputStream(OutputStream os) throws IOException {
super(os);
}
@Override
protected void writeStreamHeader() {}
}