奇怪的XmlSerializer行为

时间:2015-01-21 15:44:10

标签: c# xml xmlserializer invalidoperationexception

所以我在反序列化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个字符?

2 个答案:

答案 0 :(得分:1)

这是因为您的新文件比以前短。您应该使用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);
    }
}

答案 1 :(得分:0)

将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