问题标签 [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.

0 投票
3 回答
121 浏览

c# - 将各种类型序列化到一个文件中

我正在使用 aBinaryFormatter来序列化我的对象。我在他们的相关列表中有各种对象类型。是否有一种“最佳”方法可以将所有对象序列化到一个文件中,但能够在反序列化时将它们分开?目前,我正在反序列化整个文件并检查每个对象中的特定字段,以查看在反序列化后我应该将它们重新添加到哪个列表中。例如,我所有的福特汽车都有“福特”字段,丰田有“丰田”等。反序列化后,我“遍历”对象,检查他们的“公司”字段,然后将它们分配给List<Company>.

我不确定这是否是最有效的做事方式。有什么建议么?谢谢您的帮助

0 投票
3 回答
3417 浏览

.net - BinaryFormatter 替代品

我正在购买 BinaryFormatter 替代品/替代品。

我对 BinaryFormatter 的当前问题(替代方案应该解决这个问题)是
1)向后兼容性(可以反序列化使用早期版本序列化的类)
2)大小
3)速度

我检查了看起来不错的 AltSerializer,一些关于速度的相互矛盾的报告,但它看起来支持向后兼容性。

我还查看了protobuf-net,它看起来很棒,除了在这个阶段它需要大量工作,因为您必须定义所有 .proto 文件。

也许使用上述任何一种或其他东西的人会愿意发表评论。

0 投票
3 回答
11994 浏览

c# - 性能:BinaryFormatter 与 XmlSerializer

我经常读到 BinaryFormatter 比 XmlSerializer 具有更好的性能。出于好奇,我写了一个测试应用程序。

一个wtf时刻......为什么Xml比Bin快得多(尤其是反序列化)?

我的结果:

0 投票
2 回答
1385 浏览

.net - 如何重构在 .NET 中序列化的类?

我有一个由BinaryFormatter序列化到磁盘的 C# 类,例如这个例子:

后来,我想通过以下一项或多项来重构这个类
- 更改其名称
- 更改其命名空间
- 移动到另一个程序集

据我所知,只有具有完全相同名称、名称空间和程序集名称的类可用时,才能对二进制文件进行反序列化。

我该如何解决这个问题?是否可以在不破坏Version Tolerant Serialization
的情况下将反序列化映射到不同的类名、命名空间和程序集?

0 投票
3 回答
4383 浏览

.net - .NET 与 BinaryFormatter 的向后兼容性

我们在 C# 游戏中使用 BinaryFormatter 来保存用户游戏进度、游戏关卡等。我们遇到了向后兼容的问题。

目的:

  • 关卡设计师创建活动(关卡和规则),我们更改代码,活动应该仍然可以正常工作。在发布之前的开发过程中每天都会发生这种情况。
  • 用户保存游戏,我们发布了游戏补丁,用户应该仍然可以加载游戏
  • 无论两个版本相距多远,不可见的数据转换过程都应该有效。例如,用户可以跳过我们的前 5 个小更新并直接获得第 6 个。尽管如此,他保存的游戏应该仍然可以正常加载。

该解决方案需要对用户和关卡设计师完全不可见,并且最小化想要更改某些内容的编码人员的负担(例如,重命名字段,因为他们想到了更好的名称)。

我们序列化的一些对象图植根于一个类,一些则植根于其他类。不需要前向兼容性。

潜在的重大变化(以及当我们序列化旧版本并反序列化到新版本时会发生什么):

  • 添加字段(获取默认初始化)
  • 更改字段类型(失败)
  • 重命名字段(相当于删除它并添加一个新的)
  • 将属性更改为字段并返回(相当于重命名)
  • 更改自动实现的属性以使用支持字段(相当于重命名)
  • 添加超类(相当于将其字段添加到当前类)
  • 以不同的方式解释字段(例如,以度为单位,现在以弧度为单位)
  • 对于实现 ISerializable 的类型,我们可能会更改 ISerializable 方法的实现(例如,开始在 ISerializable 实现中对一些非常大的类型使用压缩)
  • 重命名一个类,重命名一个枚举值

我读过:

我目前的解决方案

  • 我们通过使用诸如 OnDeserializing 回调之类的东西,尽可能多地进行非破坏性更改。
  • 我们每两周安排一次重大更改,因此需要保留的兼容性代码更少。
  • 每次在进行重大更改之前,我们都会将我们使用的所有[Serializable] 类复制到名为 OldClassVersions.VersionX 的命名空间/文件夹中(其中 X 是最后一个序号之后的下一个序号)。即使我们不会很快发布,我们也会这样做。
  • 当写入文件时,我们序列化的是这个类的一个实例:class SaveFileData { int version; 对象数据;}
  • 从文件读取时,我们反序列化 SaveFileData 并将其传递给执行以下操作的迭代“更新”例程:

.

  • 为方便起见,Update() 函数在其实现中可以使用 CopyOverlappingPart() 函数,该函数使用反射将尽可能多的数据从旧版本复制到新版本。这样,Update() 函数只能处理实际更改的内容。

一些问题:

  • 反序列化器反序列化为类 Foo 而不是类 OldClassVersions.Version5.Foo - 因为类 Foo 是被序列化的。
  • 几乎不可能测试或调试
  • 需要保留很多类的旧副本,这容易出错、脆弱和烦人
  • 当我们想重命名一个类时,我不知道该怎么办

这应该是一个非常普遍的问题。人们通常如何解决它?

0 投票
1 回答
610 浏览

c# - 合并二进制数据

我正在重新格式化这个问题,使其更短且切中要害。如果我通过 BinaryFormatter 的 Serialize 方法运行一堆不同的自定义对象,我会得到一堆序列化的二进制文件。在我的应用程序中使用保存/加载功能合并这些二进制文件/检索它们的最佳方法是什么?

0 投票
4 回答
1703 浏览

c# - C# 通过异步套接字连接发送具有序列化对象的对象大小

我想序列化一个对象并通过网络发送它。我已经在我的类和 BinaryFormatter 上使用 ISerializeable 属性设置它以将对象转换为字节。我可以发送对象并在接收端反序列化它。但是,为了确保在尝试重建对象之前拥有整个对象,我想将大小与流一起发送。我想将前几个字节设置为大小,检查接收到的数据何时至少是这个固定大小,然后我可以读取它并获取对象的完整大小。然后,只需等到我收到的数据是对象的大小+固定大小的字节。如何在流中偏移我的数据,以便我可以发送一个 int 将对象的大小存储为前几个字节,并将我的对象存储为剩余字节?

0 投票
5 回答
16014 浏览

c# - 如何让 BinaryFormatter 在不同的应用程序中反序列化

我正在使用 BinaryFormatter 将类实例数组序列化为文件。我可以在同一个应用程序中反序列化这个罚款。当我在不同的应用程序中尝试相同的反序列化(拉入一个可以完成工作的通用文件)时,我收到以下错误:

其中 pmlscan 是原始应用程序的名称。如何让 BinaryFormatter 不尝试加载 pmlscan?

0 投票
1 回答
1445 浏览

.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 解决了吗?

0 投票
2 回答
406 浏览

c# - 如何反序列化对结构等效项的引用集合?

注意:随着我对该问题的了解更多,这个问题发生了一些变化,因此请完整阅读。我决定保留它的原始形式,因为它更好地描述了问题是如何被发现和最终解决的。


回到我们项目历史的最黑暗深处,当我们没有像我们可能的那样真正了解 C# 或 CLR 时,我们创建了一个类型,我们称之为MyType. 我们将此类型创建为class一个引用类型。

然而,很明显MyType应该是struct一个值类型,所以我们进行了一些更改以使其如此,一切都很好,直到有一天,我们尝试反序列化一些包含值集合的数据MyType。嗯,不是真的,因为当它是一个引用类型时,那个集合就是一个引用的集合。现在,当它反序列化时,集合可以很好地反序列化,使用 的默认构造函数MyType,然后当实际引用反序列化时,它们是孤立的,给我们留下一个空值集合。

因此,我们想,“让我们在加载时将类型映射到引用类型,MyTypeRef以便引用正确解析,然后转换回我们的真实类型以在执行时和重新序列化期间使用”。所以我们做了(使用我们自己的活页夹),但是可惜,它不起作用,因为现在我们得到一个错误,告诉我们即使我们在and之间进行了隐式转换,MyTypeRef[]也无法转换为。MyType[]MyTypeRefMyType

所以,我们被困住了。我们如何将一个集合序列化为引用类型的集合MyType以反序列化为值类型的集合MyType

更新
一些调查(见下面的评论和代码)表明,新的不可变性质MyType及其用于ISerializable序列化的特性导致了真正的问题。我仍然不明白为什么会这样,但是如果我使用privateset 访问器而不是ISerializable,新的MyType将加载旧的(请注意,ISerializable如果我使用它会调用接口,但集合甚至只包含默认值)。

一些代码

请注意,加载时,元素都是空值。ISerializable从第二个定义中删除并加载和所有工作。在加载代码上更改classstruct,并且可以看到相同的行为。就好像集合只会使用 set 访问器成功反序列化。

更新二
因此,我发现了问题(请参阅下面的答案),但我怀疑有人会通过阅读我的问题知道答案。我错过了一个重要的细节,当时我什至没有意识到这很重要。我向那些试图提供帮助的人致以最诚挚的歉意。

加载的包含MyType的集合在 期间立即复制到另一个集合GetObjectData。下面的答案解释了为什么这很重要。这是上面给出的一些附加示例代码,应该提供一个完整的示例: