5

在过去两天搜索此问题的答案后,我希望这里有人可以提供帮助。

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

“二进制流 '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();
4

1 回答 1

3

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

如果要解决版本控制问题,我偏爱protobuf-net,但我很偏颇。不过,它对我们来说非常有效。但这听起来不像通常的版本控制问题。

于 2013-04-09T17:04:33.093 回答