Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I deserialize an object when the underlying class has been changed slightly?

I've written a custom class MyClass and marked it with the <Serializable()> attribute. I have a set of binary files on my hard drive that I've serialized using BinaryFormatter that came from instances of MyClass.

I've recently changed the structure of MyClass slightly (added some properties, deleted some properties, changed a few methods, etc).

What happens when I try to deserialize the existing objects to this changed class using the code below? I've tried it and not had an error thrown or anything - but surely it can't deserialize properly when the class has changed? Is there a way I can get some useful information out of the serialized files even though I've updated the class?

Thanks.


Here's the code I'm using to do the serialization:

Public Sub serializeObject(ByVal obj As Object, ByVal outFilename As String)
    Dim fStream As FileStream
    Try
        fStream = New FileStream(outFilename, FileMode.Create)
        Dim bfmtr As New BinaryFormatter
        bfmtr.Serialize(fStream, obj)
        fStream.Close()
    Catch ex As Exception
        MsgBox("Failed to serialize: " & ex.Message)
        Throw
    End Try
End Sub

And to do the deserialization I'm using:

myObj = CType(deserializeObject("C:\myobject.bin"), MyClass))

Where deserializeObject is:

Public Function deserializeObject(ByVal srcFilename As String) As Object
    If File.Exists(srcFilename) Then
        Dim fStream As Stream = File.OpenRead(srcFilename)
        Dim deserializer As New BinaryFormatter
        Dim returnObject As Object = deserializer.Deserialize(fStream)
        fStream.Close()
        Return returnObject
    Else
        Throw New ApplicationException("File not found: " & srcFilename)
    End If
End Function
like image 645
Flash Avatar asked May 10 '11 11:05

Flash


1 Answers

In the past I have had compatability issues between minor changes in serialized objects using the binaryformatter, and I also do not fully understand why. There is a "UnsafeDeserialize" method which sort of implies a more compatible "deserialize".

The "What Happens" is when it does have a compatibility breaking change, you simply cannot recreate the object. I don't know if there is any way to recreate it again short of using old code structure.

I have used XML serialization in these cases which seems to be much safer (and is readable so you could potentially correct any issue you have later)

The cost is that the size of the XML serialized objects is considerably larger in most cases. Compressing/decompressing can help that.

Here are my XML routines I use for this.

''' <summary>
''' Serializes as object into XML format
''' This IS different then SOAP Serialization.
''' </summary>
''' <typeparam name="ObjectType">The type of the object being serialized</typeparam>
''' <param name="oObj">The object to serialize</param>
''' <returns>The XML Document (string) that is the serialized object in text form</returns>
Public Shared Function XmlSerialize(Of ObjectType)(ByVal oObj As Object) As String
    Dim sb As New System.Text.StringBuilder
    Dim sw As New IO.StringWriter(sb)
    Dim x As New System.Xml.Serialization.XmlSerializer(GetType(ObjectType))
    x.Serialize(sw, oObj)
    Return sb.ToString
End Function
''' <summary>
''' DeSerializes and object from an XML Document
''' This IS different then SOAP Serialization.
''' </summary>
''' <typeparam name="ObjectType">The Object type that will be returned (That the XML Data is derived from)</typeparam>
''' <param name="oObj">The Object (in it's XML Document serialized format)</param>
''' <returns>The new object</returns>
Public Shared Function XmlDeSerialize(Of ObjectType)(ByVal oObj As String) As ObjectType
    Dim sr As New IO.StringReader(oObj)
    Dim x As New System.Xml.Serialization.XmlSerializer(GetType(ObjectType))
    Dim out As ObjectType = CType(x.Deserialize(sr), ObjectType)
    Return out
End Function
like image 167
DarrenMB Avatar answered Nov 09 '22 01:11

DarrenMB