【问题标题】:Binary (De)Serialization of a stream of objects to 1 file将对象流二进制(反)序列化为 1 个文件
【发布时间】:2011-03-16 13:16:46
【问题描述】:

我面临以下问题。我需要将对象流(反)序列化(二进制)到磁盘上的单个文件。序列化部分不是问题,只需以附加模式打开一个流并使用 .Net 的 BinaryFormatter Serialize 方法就可以了。这种方法的问题是我不能只将此流提供给 BinaryFormatter 的反序列化函数,它包含的不是我已序列化的对象的单个实例。

此问题是否存在通用解决方案?序列化到给定流的所有对象都是相同类型的,所以至少我们不需要弄清楚要反序列化什么,这是给定的,但它似乎并没有为我提供解决方法。

基于回复的说明:预计发送的对象数量会很大,因此将它们全部保存在包装器集合中是不可行的(因为刷新到磁盘需要全部加载它们进入内存 -> 添加新的 -> 刷新到磁盘)。

  • 通常,当您序列化单个对象时,您会得到一个包含以下内容的文件:

[对象]

  • 我创建的是一个文件,其中包含:

[对象][对象][对象][对象]...[对象]

我需要反序列化各个 Object 实例。

提前致谢!

答案:由于在这个帖子中提到了答案(足够清晰),但从未明确说明,我想我会在这里陈述:

while (fileStream.Position < fileStream.Length)
    messages.Add((Message)formatter.Deserialize(fileStream));

BinaryFormatter 将根据需要一次反序列化一个对象 :) 您可能希望缓存 fileStream.Length 属性,因为每次调用该属性时都会重新计算长度,从而减慢速度。我不知道为什么我在发布这个问题之前第一次尝试它时不起作用,但现在它确实可以完美地工作。

【问题讨论】:

    标签: c# .net file serialization binary


    【解决方案1】:

    尝试将您的对象放入可序列化的集合中(我相信 List 是可序列化的),然后(反)序列化 那个 对象

    编辑以回应澄清: 我刚刚意识到这个问题与question 的答案相同。与其尝试重新发明一个答案,我只想看看 Mark Gravell 的答案,或者去this one

    【讨论】:

    • 对象在系统的生命周期内流入,预计会有非常多的对象,我需要刷新。将它们保存在 wrapper-collection 中,我将不得不将它们全部保存在内存中,并在每次我想刷新到磁盘时重新写入整个文件。
    • 第一个建议不起作用,因为需要另一个库(如果我幸运的话,通过法律获得 6 个月以上的批准过程)。第二个很有趣。对于第二个答案,似乎他们已经进行了正常的序列化,可以从一个文件中反序列化一系列对象,而这些对象不在集合中。在我的测试中没有成功,所以我想我会尝试进一步研究它+也许会跟进那个 SO 问题。
    【解决方案2】:

    一个文件一个序列化,所以我认为将你的流直接发送到一个文件会做你想要的。对您的情况进行更具体的解释将有助于提供更有用的答案。 (我希望我可以将此作为“评论”输入,但不知何故,我无法使用评论按钮。)

    【讨论】:

    • 序列化不是问题。问题是,如果我一次序列化一个对象(我必须)并将它们附加到一个流中,我无法反序列化结果流,因为整个流并不代表单个对象。
    • 基本上,通常当您将对象序列化为文件时,该文件将包含该对象(即 [Object]),因此要反序列化您执行 Object obj = binaryFormatter.Deserialize(fs, MyObjType);我所拥有的是 [Object][Object]...[Object] 形式的文件,因此我不能只在该文件上调用反序列化函数,因为我为反序列化器提供的不是单个对象的序列化。
    • 我的想法是在其中添加一些分隔符(前提是存在序列化程序永远无法生成的符号组合)。这样我就可以在一个流中手动将文件解析成块(代表单个序列化对象),并将块分配给另一个流,然后将其提供给反序列化器。
    猜你喜欢
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    相关资源
    最近更新 更多