问题标签 [binaryformatter]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 将各种类型序列化到一个文件中
我正在使用 aBinaryFormatter
来序列化我的对象。我在他们的相关列表中有各种对象类型。是否有一种“最佳”方法可以将所有对象序列化到一个文件中,但能够在反序列化时将它们分开?目前,我正在反序列化整个文件并检查每个对象中的特定字段,以查看在反序列化后我应该将它们重新添加到哪个列表中。例如,我所有的福特汽车都有“福特”字段,丰田有“丰田”等。反序列化后,我“遍历”对象,检查他们的“公司”字段,然后将它们分配给List<Company>
.
我不确定这是否是最有效的做事方式。有什么建议么?谢谢您的帮助
.net - BinaryFormatter 替代品
我正在购买 BinaryFormatter 替代品/替代品。
我对 BinaryFormatter 的当前问题(替代方案应该解决这个问题)是
1)向后兼容性(可以反序列化使用早期版本序列化的类)
2)大小
3)速度
我检查了看起来不错的 AltSerializer,一些关于速度的相互矛盾的报告,但它看起来支持向后兼容性。
我还查看了protobuf-net,它看起来很棒,除了在这个阶段它需要大量工作,因为您必须定义所有 .proto 文件。
也许使用上述任何一种或其他东西的人会愿意发表评论。
c# - 性能:BinaryFormatter 与 XmlSerializer
我经常读到 BinaryFormatter 比 XmlSerializer 具有更好的性能。出于好奇,我写了一个测试应用程序。
一个wtf时刻......为什么Xml比Bin快得多(尤其是反序列化)?
我的结果:
.net - 如何重构在 .NET 中序列化的类?
我有一个由BinaryFormatter序列化到磁盘的 C# 类,例如这个例子:
后来,我想通过以下一项或多项来重构这个类
- 更改其名称
- 更改其命名空间
- 移动到另一个程序集
据我所知,只有具有完全相同名称、名称空间和程序集名称的类可用时,才能对二进制文件进行反序列化。
我该如何解决这个问题?是否可以在不破坏Version Tolerant Serialization
的情况下将反序列化映射到不同的类名、命名空间和程序集?
.net - .NET 与 BinaryFormatter 的向后兼容性
我们在 C# 游戏中使用 BinaryFormatter 来保存用户游戏进度、游戏关卡等。我们遇到了向后兼容的问题。
目的:
- 关卡设计师创建活动(关卡和规则),我们更改代码,活动应该仍然可以正常工作。在发布之前的开发过程中每天都会发生这种情况。
- 用户保存游戏,我们发布了游戏补丁,用户应该仍然可以加载游戏
- 无论两个版本相距多远,不可见的数据转换过程都应该有效。例如,用户可以跳过我们的前 5 个小更新并直接获得第 6 个。尽管如此,他保存的游戏应该仍然可以正常加载。
该解决方案需要对用户和关卡设计师完全不可见,并且最小化想要更改某些内容的编码人员的负担(例如,重命名字段,因为他们想到了更好的名称)。
我们序列化的一些对象图植根于一个类,一些则植根于其他类。不需要前向兼容性。
潜在的重大变化(以及当我们序列化旧版本并反序列化到新版本时会发生什么):
- 添加字段(获取默认初始化)
- 更改字段类型(失败)
- 重命名字段(相当于删除它并添加一个新的)
- 将属性更改为字段并返回(相当于重命名)
- 更改自动实现的属性以使用支持字段(相当于重命名)
- 添加超类(相当于将其字段添加到当前类)
- 以不同的方式解释字段(例如,以度为单位,现在以弧度为单位)
- 对于实现 ISerializable 的类型,我们可能会更改 ISerializable 方法的实现(例如,开始在 ISerializable 实现中对一些非常大的类型使用压缩)
- 重命名一个类,重命名一个枚举值
我读过:
- 版本容错序列化
- IDeserializationCallback
- [可选字段(添加版本)]
- [OnDeserializing]、[OnDeserialized]、[OnSerializing]、[OnSerialized]。
- [未序列化]
我目前的解决方案:
- 我们通过使用诸如 OnDeserializing 回调之类的东西,尽可能多地进行非破坏性更改。
- 我们每两周安排一次重大更改,因此需要保留的兼容性代码更少。
- 每次在进行重大更改之前,我们都会将我们使用的所有[Serializable] 类复制到名为 OldClassVersions.VersionX 的命名空间/文件夹中(其中 X 是最后一个序号之后的下一个序号)。即使我们不会很快发布,我们也会这样做。
- 当写入文件时,我们序列化的是这个类的一个实例:class SaveFileData { int version; 对象数据;}
- 从文件读取时,我们反序列化 SaveFileData 并将其传递给执行以下操作的迭代“更新”例程:
.
- 为方便起见,Update() 函数在其实现中可以使用 CopyOverlappingPart() 函数,该函数使用反射将尽可能多的数据从旧版本复制到新版本。这样,Update() 函数只能处理实际更改的内容。
一些问题:
- 反序列化器反序列化为类 Foo 而不是类 OldClassVersions.Version5.Foo - 因为类 Foo 是被序列化的。
- 几乎不可能测试或调试
- 需要保留很多类的旧副本,这容易出错、脆弱和烦人
- 当我们想重命名一个类时,我不知道该怎么办
这应该是一个非常普遍的问题。人们通常如何解决它?
c# - 合并二进制数据
我正在重新格式化这个问题,使其更短且切中要害。如果我通过 BinaryFormatter 的 Serialize 方法运行一堆不同的自定义对象,我会得到一堆序列化的二进制文件。在我的应用程序中使用保存/加载功能合并这些二进制文件/检索它们的最佳方法是什么?
c# - C# 通过异步套接字连接发送具有序列化对象的对象大小
我想序列化一个对象并通过网络发送它。我已经在我的类和 BinaryFormatter 上使用 ISerializeable 属性设置它以将对象转换为字节。我可以发送对象并在接收端反序列化它。但是,为了确保在尝试重建对象之前拥有整个对象,我想将大小与流一起发送。我想将前几个字节设置为大小,检查接收到的数据何时至少是这个固定大小,然后我可以读取它并获取对象的完整大小。然后,只需等到我收到的数据是对象的大小+固定大小的字节。如何在流中偏移我的数据,以便我可以发送一个 int 将对象的大小存储为前几个字节,并将我的对象存储为剩余字节?
c# - 如何让 BinaryFormatter 在不同的应用程序中反序列化
我正在使用 BinaryFormatter 将类实例数组序列化为文件。我可以在同一个应用程序中反序列化这个罚款。当我在不同的应用程序中尝试相同的反序列化(拉入一个可以完成工作的通用文件)时,我收到以下错误:
其中 pmlscan 是原始应用程序的名称。如何让 BinaryFormatter 不尝试加载 pmlscan?
.net-3.5 - .Net 3.5 中 BinaryFormatter 类的内存泄漏问题
我在 .Net 3.5 框架中看到 BinaryFormatter 类的内存泄漏问题。我正在使用以下方法来反序列化一个对象。传递给此方法的字节数组大小为 156MB。但是,我调用这个方法后有 2.6GB 的跳跃。
我在 MSDN 上找到了这篇文章,讨论了这个内存泄漏问题。http://blogs.msdn.com/b/psirr/archive/2009/11/13/interesting-memory-leak-in-net-3-5-binary-deserialization.aspx
有谁知道这个问题是否有解决方案?.Net 4.0 解决了吗?
c# - 如何反序列化对结构等效项的引用集合?
注意:随着我对该问题的了解更多,这个问题发生了一些变化,因此请完整阅读。我决定保留它的原始形式,因为它更好地描述了问题是如何被发现和最终解决的。
回到我们项目历史的最黑暗深处,当我们没有像我们可能的那样真正了解 C# 或 CLR 时,我们创建了一个类型,我们称之为MyType
. 我们将此类型创建为class
一个引用类型。
然而,很明显MyType
应该是struct
一个值类型,所以我们进行了一些更改以使其如此,一切都很好,直到有一天,我们尝试反序列化一些包含值集合的数据MyType
。嗯,不是真的,因为当它是一个引用类型时,那个集合就是一个引用的集合。现在,当它反序列化时,集合可以很好地反序列化,使用 的默认构造函数MyType
,然后当实际引用反序列化时,它们是孤立的,给我们留下一个空值集合。
因此,我们想,“让我们在加载时将类型映射到引用类型,MyTypeRef
以便引用正确解析,然后转换回我们的真实类型以在执行时和重新序列化期间使用”。所以我们做了(使用我们自己的活页夹),但是可惜,它不起作用,因为现在我们得到一个错误,告诉我们即使我们在and之间进行了隐式转换,MyTypeRef[]
也无法转换为。MyType[]
MyTypeRef
MyType
所以,我们被困住了。我们如何将一个集合序列化为引用类型的集合MyType
以反序列化为值类型的集合MyType
?
更新
一些调查(见下面的评论和代码)表明,新的不可变性质MyType
及其用于ISerializable
序列化的特性导致了真正的问题。我仍然不明白为什么会这样,但是如果我使用private
set 访问器而不是ISerializable
,新的MyType
将加载旧的(请注意,ISerializable
如果我使用它会调用接口,但集合甚至只包含默认值)。
一些代码
请注意,加载时,元素都是空值。ISerializable
从第二个定义中删除并加载和所有工作。在加载代码上更改class
为struct
,并且可以看到相同的行为。就好像集合只会使用 set 访问器成功反序列化。
更新二
因此,我发现了问题(请参阅下面的答案),但我怀疑有人会通过阅读我的问题知道答案。我错过了一个重要的细节,当时我什至没有意识到这很重要。我向那些试图提供帮助的人致以最诚挚的歉意。
加载的包含MyType
的集合在 期间立即复制到另一个集合GetObjectData
。下面的答案解释了为什么这很重要。这是上面给出的一些附加示例代码,应该提供一个完整的示例: