当底层类发生轻微更改时,我可以反序列化对象吗?

发布于 2024-11-06 16:50:28 字数 1479 浏览 5 评论 0原文

我编写了一个自定义类 MyClass 并用 属性对其进行标记。我的硬盘上有一组二进制文件,我使用来自 MyClass 实例的 BinaryFormatter 序列化了这些文件。

我最近稍微改变了 MyClass 的结构(添加了一些属性,删除了一些属性,更改了一些方法等)。

当我尝试使用下面的代码将现有对象反序列化到这个已更改的类时会发生什么?我已经尝试过并且没有抛出错误或任何东西 - 但肯定它无法正确反序列化班级变了?即使我更新了类,有没有办法可以从序列化文件中获取一些有用的信息?

谢谢。


这是我用来进行序列化的代码:

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

以及我用来进行反序列化的代码:

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

其中 deserializeObject 是:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

会傲 2024-11-13 16:50:28

过去,我在使用二进制格式化程序对序列化对象进行细微更改之间遇到了兼容性问题,而且我也不完全理解原因。有一种“UnsafeDeserialize”方法,这意味着更兼容的“反序列化”。

“会发生什么”是当它确实发生了兼容性破坏性更改时,您根本无法重新创建该对象。我不知道是否有任何方法可以在不使用旧代码结构的情况下再次重新创建它。

在这些情况下,我使用了 XML 序列化,这似乎更安全(并且可读,因此您可以纠正以后遇到的任何问题)。

代价是,在大多数情况下,XML 序列化对象的大小要大得多。压缩/解压缩可以帮助实现这一点。

以下是我为此使用的 XML 例程。

''' <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

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
ゞ记忆︶ㄣ 2024-11-13 16:50:28

您将需要控制序列化和反序列化过程。
您可以使用 ISerialized 接口来执行此操作。

看看:

http://msdn.microsoft .com/en-us/library/ty01x675.aspx,“实现 ISerialized 接口”部分中有一些有用的信息。

You will need to control the serialization and deserialization process.
You may use the ISerializable interface to do this.

Take a look at:

http://msdn.microsoft.com/en-us/library/ty01x675.aspx, there is some useful information in the section "Implementing the ISerializable Interface".

北恋 2024-11-13 16:50:28

添加和删​​除字段不应该有任何问题 - 我有经验证明,但我不知道序列化的详细工作原理。

更改私有属性的名称时可能会遇到问题。所有其他事情,甚至重新排序字段,你都很酷。

Adding and removing fields SHOULD NOT be of any problem - I have empirical proof of that, not that I know how the serialization works in the detail.

You could have problems when changing the name of the private properties. All other things, even reordering the fields, you're cool.

烧了回忆取暖 2024-11-13 16:50:28

我还没有看过 BinaryFormatter.Deserialize() 的实际实现,所以我会推测。

我不认为反序列化器有责任确保类的所有属性不为空。在很多情况下,空属性是完全有效的并且不会引起任何问题。

现在我可以回答您的问题:

我相信向类添加属性不会导致问题,但是,我确实认为删除您尝试反序列化的属性会导致错误。

I haven't looked at the actual implementation of BinaryFormatter.Deserialize() so I will speculate.

I dont think that it is the responsibility of the deserializer to ensure that all the properties of a class are not null. There are plenty of scenarios where null properties are totally valid and cause no problems.

Now I can answer your question:

I believe that adding properties to a class will not cause problems however, I do think that removing properties that you are attempting to deserialize will cause errors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文