反序列化不适用于MemoryStream

//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(); 

如果我尝试使用上面的方式反序列化,它会将exception作为

‘二进制流’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()来填充字节数组。 exception的原因是什么。

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

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

 ms.Seek(0, SeekOrigin.Begin); 

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

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

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