5

過去 2 日間、この問題に対する回答を探した後、ここの誰かが助けてくれることを願っています。

BinaryFormatter を使用してユーザーのプロジェクト データを保存し、ファイルに保存する前にシリアル化可能なクラスを Stream にシリアル化するプログラムを VS2012 を使用して c# で作成しました。このプログラムはしばらく使用されていますが、最近、あるユーザーが前日に保存したファイルを開くことができませんでした。彼は私にファイルを送ってくれました。デガガーに表示されるエラーは次のとおりです。

「バイナリ ストリーム '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 に答える