反序列化不适用于MemoryStream

时间:2010-02-09 12:08:44

标签: c# serialization

//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()填充字节数组。 异常的原因是什么。

2 个答案:

答案 0 :(得分:16)

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

您可以将MemoryStream中的位置移动到开头,然后再读取它:

ms.Seek(0, SeekOrigin.Begin);

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

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

答案 1 :(得分:0)

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