奇怪的 XmlSerializer 行为

Strange XmlSerializer behavior

所以我在反序列化 XML 文件时遇到了一些问题。
我正在使用以下结构。

[Serializable]
public struct GraphicsOptions
{
    public int Height;
    public int Width;
    public bool Fullscreen;
    public bool AntiAliasing;
    public int ClickResCount;
}

和下面的代码来创建,

public void CreateData()
{
    graphicsOptions.Height = graphics.PreferredBackBufferHeight;
    graphicsOptions.Width = graphics.PreferredBackBufferWidth;
    graphicsOptions.Fullscreen = graphics.IsFullScreen;
    graphicsOptions.AntiAliasing = graphics.PreferMultiSampling;
    graphicsOptions.ClickResCount = 1;
    dataStream = File.Create(SavegamePath);
    XmlSerializer serializer = new XmlSerializer(typeof(GraphicsOptions));
    serializer.Serialize(dataStream, graphicsOptions);
    dataStream.Close();
}

改变和

private void ApplyChanges()
{
    graphicsOptions.Height = graphics.PreferredBackBufferHeight;
    graphicsOptions.Width = graphics.PreferredBackBufferWidth;
    graphicsOptions.Fullscreen = graphics.IsFullScreen;
    graphicsOptions.AntiAliasing = graphics.PreferMultiSampling;
    graphicsOptions.ClickResCount = clickCountResolution;
    dataStream = File.Open(SavegamePath, FileMode.Open);
    XmlSerializer serializer = new XmlSerializer(typeof(GraphicsOptions));
    serializer.Serialize(dataStream, graphicsOptions);
    dataStream.Close();
}

加载 XML 文件

public void LoadData()
{
    dataStream = File.Open(SavegamePath, FileMode.Open);
    XmlSerializer serializer = new XmlSerializer(typeof(GraphicsOptions));
    graphicsOptions = (GraphicsOptions)serializer.Deserialize(dataStream);
    dataStream.Close();
 }

非常标准的东西,除了我第三次应用更改后它决定在文件末尾添加 2 个字符:"s>"

我不知道它为什么这样做,但它使 XML 实际上没用,因为我无法将信息加载到我的 struct.
Visual Studio 给我一个 InvalidOperationException(我明白它为什么这样做)。

关于如何防止这种情况发生或者如果捕获到异常如何简单地删除这 2 个字符有什么建议或想法吗?

这是因为您的新文件比以前短。您应该使用 FileMode.Create 而不是 Open/OpenOrCreate

所以你的保存函数应该是这样的::

private void ApplyChanges()
{
    graphicsOptions.Height = graphics.PreferredBackBufferHeight;
    graphicsOptions.Width = graphics.PreferredBackBufferWidth;
    graphicsOptions.Fullscreen = graphics.IsFullScreen;
    graphicsOptions.AntiAliasing = graphics.PreferMultiSampling;
    graphicsOptions.ClickResCount = clickCountResolution;
    using(dataStream = File.Open(SavegamePath, FileMode.Create))
    {
        XmlSerializer serializer = new XmlSerializer(typeof(GraphicsOptions));
        serializer.Serialize(dataStream, graphicsOptions);
    }
}

更改 ApplyChanges() 方法以使用另一个 FileMode,如 FileMode.Create。您可以在下面找到正确的方法。

 private void ApplyChanges()
 {
    graphicsOptions.Height = graphics.PreferredBackBufferHeight;
    graphicsOptions.Width = graphics.PreferredBackBufferWidth;
    graphicsOptions.Fullscreen = graphics.IsFullScreen;
    graphicsOptions.AntiAliasing = graphics.PreferMultiSampling;
    graphicsOptions.ClickResCount = clickCountResolution;
    dataStream = File.Open(SavegamePath, FileMode.Create); // You can use FileMode.Truncate as well.
    XmlSerializer serializer = new XmlSerializer(typeof(GraphicsOptions));
    serializer.Serialize(dataStream, graphicsOptions);
    dataStream.Close();
  }

https://msdn.microsoft.com/en-us/library/system.io.filemode(v=vs.110).aspx