I'm currently serializing HighScoreData from a C# application to an XML file using the XmlSerializer namespace. This is producing an inconsistent result regarding the outputted XML file.
The object I'm serializing is the following struct:
namespace GameProjectTomNijs.GameComponents
{
[Serializable]
public struct HighScoreData
{
public string[] PlayerName;
public int[] Score;
public int Count;
public readonly string HighScoresFilename;
public HighScoreData(int count)
{
PlayerName = new string[count];
Score = new int[count];
Count = count;
HighScoresFilename = "highscores.lst";
}
}
}
Questionable variable accessibility levels aside, it contains an array of string, an array of integers and an integer containing the total objects. This is the data that is being serialized. The output of this usually is :
<?xml version="1.0"?>
<HighScoreData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PlayerName>
<string />
<string>MISTERT</string>
<string>TESTER</string>
<string>PAULA</string>
<string>JENS</string>
</PlayerName>
<Score>
<int>554</int>
<int>362</int>
<int>332</int>
<int>324</int>
<int>218</int>
</Score>
<Count>5</Count>
</HighScoreData>
However, about 20-30% of the time it is writing to the XML file in a peculiar manner, the ending root tag would look as follows: </HighScoreData>oreData>
It seems the method writing to the XML file is appending the values rather than overwriting I guess?
The following code is the method actually writing to the XML file:
public static void SaveHighScores(HighScoreData data, string fullpath)
{
// Open the file, creating it if necessary
FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate);
try
{
// Convert the object to XML data and put it in the stream
XmlSerializer serializer = new XmlSerializer(typeof(HighScoreData));
serializer.Serialize(stream, data);
}
finally
{
// Close the file
stream.Close();
}
}`
Is there anything I'm currently overlooking? I've used this method in a large number of projects to great success. Any help would be greatly appreciated !
This is the problem:
FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate);
That doesn't truncate the file if it already exists - it just overwrites the data that it writes, but if the original file is longer than the data written by the serializer, the "old" data is left at the end.
Just use
using (var stream = File.Create(fullPath))
{
...
}
(Then you don't need try/finally either - always use a using
statement for resources...)
See more on this question at Stackoverflow