Skip to content Skip to sidebar Skip to footer

Change The Path / Class Name Of A Serialized Java Object After Refactoring

I've launched an app that saves its state with serialized object myfirstpath.UserState. Now for I want to change the path of this object to mycleanpath.UserState (same object, only

Solution 1:

I wrote a little piece of code to search/replace the old path/new path in the file containing the serialized data. I convert the file before I load it, this way I can move the serialized class to the new path without keeping copy of this class at the old path. This is how you you use it :

FilebaseDirectory= applicationContext.getFilesDir();
Filefile=newFile( baseDirectory, "settings.data" );
if (file.exists()) {
    //We have to convert it to newsettings.Databyte[] convertedBytes = common.utils.SerializeTools.changePathInSerializedFile(file, "old.path.data", "new.path.data");

    //Write converted fileFilenewFile=newFile( baseDirectory, "newsettings.data" );
    FileOutputStreamfos=newFileOutputStream(newFile);
    fos.write(convertedBytes);
    fos.close();

    //Remove old file
    file.delete();
}

And this is the code of SerializeTools.java. I've learned the java Serialize format in this great blog post http://www.javaworld.com/community/node/2915 .

package common.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

publicclassSerializeTools {

staticpublicbyte[] changePathInSerializedFile(File f, String fromPath, String toPath) throws IOException {
    byte[] buffer = newbyte[(int)f.length()];
    FileInputStreamin=newFileInputStream(f);
    in.read(buffer);
    in.close();
    return SerializeTools.changePathInSerializedData(buffer,fromPath,toPath);
}

staticpublicbyte[] changePathInSerializedData(byte[] buffer, String fromPath, String toPath) throws IOException {
    byte[] search = fromPath.getBytes("UTF-8");
    byte[] replace = toPath.getBytes("UTF-8");

    ByteArrayOutputStreamf=newByteArrayOutputStream();

    for (int i=0;i<buffer.length;i++) {
        //Search 2 bytes ahead to let us modify the 2 bytes length of the class name (see Serialize format http://www.javaworld.com/community/node/2915 )boolean found=false;
        int searchMaxIndex=i+search.length+2;
        if (searchMaxIndex<=buffer.length) {
            found=true;
            for (int j=i+2;j<searchMaxIndex;j++) {
                if (search[j-i-2]!=buffer[j]) {
                    found=false;
                    break;
                }
            }
        }
        if (found) {
            int high=((int)(buffer[i])&0xff);
            int low=((int)(buffer[i+1])&0xff);
            int classNameLength=(high<<8)+low;
            classNameLength+=replace.length-search.length;
            //Write new length
            f.write((classNameLength>>8)&0xff);
            f.write((classNameLength)&0xff);
            //Write replacement path
            f.write(replace);
            i=searchMaxIndex-1;
        } else {
            f.write(buffer[i]);
        }
    }

    f.flush();
    f.close();

    return f.toByteArray();
}

}

Solution 2:

You must implement the method readResolve, mentioned at Serializable Javadoc, in your myfirstpath.UserState class. This readResolve must return the mycleanpath.UserState object.

Post a Comment for "Change The Path / Class Name Of A Serialized Java Object After Refactoring"