【问题标题】:Deserialization not working on MemoryStream反序列化不适用于 MemoryStream
【发布时间】:2010-02-09 12:08:44
【问题描述】:
//Serialize the Object
MemoryStream ms = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms , ObjectToSerialize);
byte[] arrbyte = new byte[ms .Length];
ms.Read(arrbyte , 0, (int)ms .Length);
ms.Close();

//Deserialize the Object
Stream s = new MemoryStream(arrbyte);
s.Position = 0;
Object obj = formatter.Deserialize(s);//Throws an Exception
s.Close();

如果我尝试使用上述方式反序列化,则会将异常显示为

'二进制流 '0' 不包含有效的 BinaryHeader。可能的原因是无效的流或序列化和反序列化之间的对象版本更改。'

下面的代码在哪里工作

//Serialize the Object
IFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
formatter.Serialize(ms, ObjectToSerialize);
ms.Seek(0, SeekOrigin.Begin);
byte[] arrbyte = ms.ToArray();

//Deserialize the Object
Stream s= new MemoryStream(byt);
stream1.Position = 0;
Object obj = formatter.Deserialize(s);
stream1.Close();

唯一的区别是第一种方法使用 Read 方法填充字节数组,而第二种方法使用 Seek & ToArray() 填充字节数组。 异常的原因是什么。

【问题讨论】:

    标签: c# serialization


    【解决方案1】:

    第一种方法将对象序列化为 MemoryStream,这导致 MemoryStream 位于写入字节的末尾。从那里您将所有字节读取到字节数组的末尾:无(因为 MemoryStream 已经在末尾了)。

    您可以在读取之前将 MemoryStream 中的位置移动到开头:

    ms.Seek(0, SeekOrigin.Begin);
    

    但是代码随后与第二种方式完全相同:创建一个 ms.Length 长度的新字节数组,并将流中的所有字节复制到字节数组。那么为什么要重新发明轮子呢?

    请注意,第二种方式不需要 Seek as ToArray 始终复制所有字节,与 MemoryStream 的位置无关。

    【讨论】:

    • 啊,太好了,我盯着它看了一会儿想弄明白:)
    • @dtb,谢谢。现在我明白了这个问题
    【解决方案2】:

    在第一种情况下,您应该在读取流的内容之前查找流的开头,而在第二种情况下,在 ToArray 调用之前不需要查找。

    【讨论】:

      猜你喜欢
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-20
      相关资源
      最近更新 更多