首页 新闻 会员 周边 捐助

【求教】关于二进制反序列化报错的问题!

0
悬赏园豆:15 [已解决问题] 解决于 2015-07-23 09:54
 1             //序列化
 2             string result = string.Empty;            
 3             using (MemoryStream stream = new MemoryStream())
 4             {
 5                 BinaryFormatter formatter = new BinaryFormatter();
 6                 formatter.Serialize(stream, payslip);
 7                 byte[] objectBytes = new byte[stream.Length];
 8                 stream.Read(objectBytes, 0, (int)stream.Length);
 9 
10                 result = Convert.ToBase64String(objectBytes,Base64FormattingOptions.None);
11 
12             }
13 
14 
15             //反序列化
16             byte[] array = Convert.FromBase64String(result);
17             using (MemoryStream stream = new MemoryStream(array))
18             {
19                 BinaryFormatter de = new BinaryFormatter();
20                 object obj = de.Deserialize(stream);
21             }


 

部分代码如上,在执行到上面的代码第20行,反序列化时报错如下:

二进制流“0”不包含有效的 BinaryHeader。这可能是由于无效流,或由于在序列化和反序列化之间的对象版本更改

上面的测试代码为了排除其他原因,都写在一个方法体内,序列化后立马反序列化:

  1,先将payslip对象序列化为字节组。

  2,再将字节组反序列化为对象。

直接报错, 后来在搜索了一下答案,说可以加个Base64转换操作,加了之后还是报一样的错!

特此向大家求教!

庸俗的主页 庸俗 | 初学一级 | 园豆:190
提问于:2015-07-22 23:43
< >
分享
最佳答案
0

为什么加个 Base64 转换操作就正确了?你应该没想过这个问题吧!

而事实是你对 Stream 的使用错误。

formatter.Serialize(stream, payslip);

执行此语句后,stream 的当前读写位置已经移动到流的尾部了,所以你再执行 stream.Read 的时候,它是从流的尾部开始读取,而你想要的是从流的开始位置读取。

因此,正确的代码应该是这样:

formatter.Serialize(stream, payslip);

stream.SeekToBegin();

stream.Read(objectBytes, 0, (int)stream.Length);

然后你就可以使用 objectBytes 来构建新的 MemoryStream,并反序列化。

 

事实上,如果你在出现错误后,能够一步一步的跟踪下变量的值,你也应该发现问题,比如在 stream.Read(objectBytes, 0, (int)stream.Length) 语句调用后,你观察下 objectBytes 中的值。

收获园豆:15
Launcher | 高人七级 |园豆:45050 | 2015-07-23 09:15

谢谢你,确实是Stream读取位置造成的。我在Read之前重新设置了Postion就好了

stream.Position = 0;

还是对Stream理解不深。事实上我调试时确实发现objectBytes中都是0,但是不知道是什么原因造成的。

十分感谢!

庸俗 | 园豆:190 (初学一级) | 2015-07-23 09:50

@庸俗: 另外 Stream.Read 是有反回值的,返回值表示实际读取了多少字节的数据,由于你写的代码本身逻辑不严谨,所以导致你无法很快发现错误,如果你一开始写代码时就考虑到返回值为 0 ,或者小于你需要读取的字节数的情况的话,虽然你的代码量会增加几行,但是却能避免错误的发生。

Launcher | 园豆:45050 (高人七级) | 2015-07-23 10:02

@Launcher:  Stream.Read 的返回值这个了解,如果当时检查下应该是可以发现问题的。

庸俗 | 园豆:190 (初学一级) | 2015-07-23 10:45
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册