二进制流'0'在反序列化时不包含有效的BinaryHeader错误

der*_*ash 5 c# binaryformatter deserialization

在过去2天搜索到这个问题的答案后,我希望有人可以提供帮助.

我使用VS2012在c#中编写了一个程序,它使用BinaryFormatter保存用户的项目数据,将序列化类序列化为Stream,然后将其保存到文件中.该程序已经使用了一段时间,但是最近用户无法打开他前一天保存的文件.他把文件发给我了,我在degugger中得到的错误是:

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

鉴于用户在前一天保存了数据,序列化和反序列化之间的基础对象结构或格式没有变化.

之前没有出现过这个问题,导致我认为它必须是非常间歇性的,因此序列化和反序列化的对象没有明显的问题.

我的问题是:

我对这个错误的理解是序列化数据的格式与被反序列化的对象的格式不匹配.它是否正确?还有其他原因吗?

如果是这样,可能导致这种间歇性错误的原因是什么?

有没有办法从这个文件中检索数据,即使BinaryFormatter不认为它的格式正确?

有更安全的方法来保存和加载数据吗?我已经看到XmlFormatter似乎是一个更好的选择,但是这将如何帮助确保保存和调用的数据的完整性?

如果有帮助,我用来序列化/反序列化的代码如下:

//serialize

SEProjectData serializedProject = serializeProjectData();

Stream stream = File.Open(saveFileDialog1.FileName, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, serializedProject);
stream.Close();

//deserialize

Stream stream = File.Open(path, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();

stream.Seek(0, SeekOrigin.Begin);

SEProjectData projectData = (SEProjectData)bFormatter.Deserialize(stream);
stream.Close();
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 3

是的,BinaryFormatter 可能是版本不宽容的(特别是如果您更改字段),但这通常会引发不同的错误。您显示的代码或多或少都很好(我会使用“使用”来确保异常时迅速关闭)。没有复制品很难发表评论 - 我在想“损坏的文件”。你有文件吗?它的长度可能为零吗?它是否曾经被传输或存储在文件系统以外的地方?有多种方法可以弄乱文件内容(请参阅http://marcgravell.blogspot.com/2013/02/how-many-ways-can-you-mess-up-io.html)。

如果你想解决版本控制问题,我偏向protobuf-net,但我非常有偏见。但它对我们来说效果非常好。但这听起来不太像通常的版本控制问题。

  • 你是对的,马克,这是一个损坏的文件。我查看了引发异常时的流读取位置,检查了文件的该部分,发现文件中有一个很大的区域仅由 00 组成,这显然是不正确的。担心文件在序列化期间或保存后被损坏。我唯一能想到的就是保存后立即重新加载和反序列化文件以检查其完整性,然后在文件无法正确反序列化时提醒用户。再次感谢您的帮助。 (2认同)