我正在开发一个视频游戏,该游戏使用C#的binaryformatter保存/加载玩家的savegame。这在99%的时间内都有效,但是有时用户的savegame会以某种方式被破坏,然后游戏将无法读取文件。但是,如果我能检测到游戏何时遇到此问题,我可以告诉它加载上一个良好的savegame的备份副本,这对每个人都有帮助。
这是我加载数据的方式:
if (File.Exists(Application.persistentDataPath + "/" + saveLoad.saveFileName))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/" + saveLoad.saveFileName, FileMode.Open);
saveLoad.savedGames = (List<savedGame_latest>)bf.Deserialize(file);
file.Close();
success = true;
}
顺便说一句,这是游戏加载损坏的文件时的错误:
EndOfStreamException: Failed to read past end of stream
有什么想法吗?我想要的基本上是系统检测“哎呀,那是损坏的”,然后被分流以尝试加载最后一个安全备份的方法。
答案 0 :(得分:0)
好,您必须打开文件以检查它是否正在打开。 您可以做的是建立一个检查文件是否可以打开的功能-
要检查损坏的文件
protected virtual bool IsFileCorrupted(FileInfo file)
{
FileStream stream = null;
try
{
stream = File.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
// File is corrupted
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not corrupted
return false;
}
答案 1 :(得分:0)
由于BinaryFormatter
停止读取流后,您可以在保存的内容之后简单地添加一些哈希或校验和值,而不会破坏功能。
仅捕获EndOfStreamException
只会检测到一个可能的损坏。
保存(hashAlg
可以是任何HashAlgorithm
实现):
new BinaryFormatter().Serialize(stream, savegame); // regular data
var hash = hashAlg.ComputeHash(stream.ToArray());
stream.Write(hash, 0, hash.Length); // hash
并加载:
int hashLength = hashAlg.HashSize / 8; // get hash size in bytes
var bytes = stream.ToArray();
hash = hashAlg.ComputeHash(bytes, 0, (int)stream.Length - hashLength);
if (!hash.SequenceEqual(bytes.Skip(bytes.Length - hashLength)))
throw new ArgumentException("Savegame Corrupted"); // gotcha!
savegame = (SaveGame)new BinaryFormatter().Deserialize(stream);
return savegame;
也尝试online。