I have to work an an old application that used binaryFormatter to serialize application data into filestream (say in a file named "data.oldformat") without any optimizazion the main class has been marked with attribute
<serializable()>public MainClass
.......
end class
and the serialization code
dim b as new binaryformatter
b.serialize(mystream,mymainclass)
In an attempt to optimize the serialization/deserialization process I simply made the class implement the ISerializable interface and wrote some optimized serialization routines
<serializable()>public MainClass
implements ISerializable
.......
end class
The optimization works really well but I MUST find a way to reatrive the data inside the old files for backward compatibility.
How can I do that??
Pierluigi
Just try the same thing you've been doing so far
Implementing ISerializable didn't change your original class, basically you've just added some methods
stmax has an excellent answer, however I would implement it like this, which uses
SerializationEntry.GetEnumerator()
instead oftry/catch
. This way is cleaner and significantly faster.I would prefer a LINQ version using .FirstOrDefault(), but SerializationInfo does not implement IEnumerable - in face, weirdly enough, it doesn't even implement the old IEnumerable interface.
When serializing your objects add an additional Version field (this shouldn't add too much overhead). Then in your GetObjectData method, try to retrieve the version field first and based on whether this exists or not (by catching the SerializationException) deserialize the old way or the new way. The old way will have just serialized all data so you should just be able to call Get... for all fields.
since you've already implemented the ISerializable interface, you've probably also already added the required constructor:
you can use the info-object passed to the constructor to retrieve data from the serialized file. by default (i.e. when no ISerializable is implemented), the fields names are used as identifiers during serialization. so if your old class had a field "int x" you can deserialize this using:
for newer versions i normally add a "version" entry during serialization, like this:
during deserialization you can check this version entry and deserialize accordingly:
i haven't compiled that code, might contain typos.
hope that helps.
Your previous code should work. Do you get an exception? Try to use new constructor: