0

So i'm having some trouble deserializing an XML file.
I'm using the following struct.

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

And the following code to Create,

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();
}

Change and

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();
}

Load the XML file

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

Pretty standard stuff, except after the third time I apply the changes it decides to add 2 characters at the end of the file: "s>".

I have no idea why it does this, but it makes the XML practically useless because I can't load the information into my struct.
Visual Studio is giving me an InvalidOperationException (I understand why it does this).

Any advice or ideas on how to prevent this from occuring or how to simply delete the 2 characters if it catches the exception?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
Matonster
  • 3
  • 2
  • It would really help if you'd just give us a short but complete program demonstrating the problem - which only needs to save the file, really. – Jon Skeet Jan 21 '15 at 15:46
  • did i give too much information or not enough? the program in question is made with the XNA framework, i can add the update logic, but it wont really give you any more information – Matonster Jan 21 '15 at 15:51
  • A mixture - too much (i.e. some extraneous stuff) and not enough (not a short but complete program demonstrating the problem). XNA is *probably* irrelevant - but it would be easy to tell if you'd just create a short console app (not snippets, just a whole program) which shows the issue. – Jon Skeet Jan 21 '15 at 15:52
  • did you try dataStream.Flush() after every write operation? – Pankaj Kapare Jan 21 '15 at 15:53
  • good advice, i tried it but no cigar. – Matonster Jan 21 '15 at 16:03

2 Answers2

1

It happens because your new file is short than it was previously. You should use FileMode.Create instead of Open/OpenOrCreate

So Your save function should look like this::

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);
    }
}
MNie
  • 1,347
  • 1
  • 15
  • 35
0

Change the ApplyChanges() method to use another FileMode, like FileMode.Create. You can find the correct method below.

 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();
  }

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