当底层类发生轻微更改时,我可以反序列化对象吗?
我编写了一个自定义类 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
过去,我在使用二进制格式化程序对序列化对象进行细微更改之间遇到了兼容性问题,而且我也不完全理解原因。有一种“UnsafeDeserialize”方法,这意味着更兼容的“反序列化”。
“会发生什么”是当它确实发生了兼容性破坏性更改时,您根本无法重新创建该对象。我不知道是否有任何方法可以在不使用旧代码结构的情况下再次重新创建它。
在这些情况下,我使用了 XML 序列化,这似乎更安全(并且可读,因此您可以纠正以后遇到的任何问题)。
代价是,在大多数情况下,XML 序列化对象的大小要大得多。压缩/解压缩可以帮助实现这一点。
以下是我为此使用的 XML 例程。
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.
您将需要控制序列化和反序列化过程。
您可以使用 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".
添加和删除字段不应该有任何问题 - 我有经验证明,但我不知道序列化的详细工作原理。
更改私有属性的名称时可能会遇到问题。所有其他事情,甚至重新排序字段,你都很酷。
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.
我还没有看过 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.