سؤال

I am trying to create a method to save some basic data to an xml file. I can create the file, and serialize it, but when I try to edit information, the next time I try to deserialize it throws an exception - here is an error in XML document (10, 10).

So clearly when I try to serialize the file after the first time I am doing it in such a way that it messes up the integrity. I cant find what is ruining the file, so wondered if anyone could offer some advise - am I re-writing the data correctly?

Here is the code that is causing the problem and the Data types are below:

#if WINDOWS_PHONE
        IsolatedStorageFile dataFile = IsolatedStorageFile.GetUserStoreForApplication();
#else
        IsolatedStorageFile dataFile = IsolatedStorageFile.GetUserStoreForDomain();
#endif
        try
        {
            // Create an isolated storage stream and initialize it as null.
            IsolatedStorageFileStream isolatedFileStream = null;
            // Open the isolated storage stream, and write the save data file.
            if (dataFile.FileExists(filename))
            {
                using (isolatedFileStream = dataFile.OpenFile(filename, FileMode.Open, FileAccess.ReadWrite))
                {

                    // Read the data from the file.
                    XmlSerializer serializer = new XmlSerializer(typeof(Data));
                    // Store each of the deserialized data objects in the list.
                    Data savedData = (Data)serializer.Deserialize(isolatedFileStream);

                    // Loop through the saved data objects.
                    for(int i = 0; i < savedData.Levels.Count; i++)
                    {

                        System.Diagnostics.Debug.WriteLine("I am inside the loop and my index is" + i);
                        // Get the data object in question.
                        LevelData levelData = savedData.Levels[i];

                        // Check to see if the index of the data object corresponds to the active level index.
                        if (levelData.Index == mLevelIndex)
                        {
                            // Check that the attempts already saved is less.
                            if (levelData.Attempts < mLevel.AttemptCounter)
                                levelData.Attempts = mLevel.AttemptCounter;

                            // Check that the 
                            if (levelData.PercentComplete < 50)
                                levelData.PercentComplete = 50;
                        }
                    }
                    serializer.Serialize(isolatedFileStream, savedData);
                }  
            }

Data

public struct Data
{
    /// <summary>
    /// The Level data object.
    /// </summary>
    [XmlArray(ElementName = "Levels")]
    public List<LevelData> Levels;
}

//LevelData
public struct LevelData
{
    /// <summary>
    /// The index of the level.
    /// </summary>
    [XmlElement(ElementName = "Index")]
    public int Index;

    /// <summary>
    /// The number of attempts the player has made for a particular level.
    /// </summary>
    [XmlElement(ElementName = "Attempts")]
    public int Attempts;

    /// <summary>
    /// A value describing the furthest the player has ever got within the level.
    /// </summary>
    [XmlElement(ElementName = "PercentComplete")]
    public int PercentComplete;
}
هل كانت مفيدة؟

المحلول

You're writing to isolatedFileStream after reading the XML content from it. Thus appending a new version to the file.

You should Seek to the beginning of the file, write the new content and truncate the file.

Or just close the stream and open another one with FileMode.Create.

Here is how I would implement the first solution:

using (isolatedFileStream = dataFile.OpenFile(filename, FileMode.Open, FileAccess.ReadWrite))
{

    // Read the data from the file.
    XmlSerializer serializer = new XmlSerializer(typeof(Data));
    // Store each of the deserialized data objects in the list.
    Data savedData = (Data)serializer.Deserialize(isolatedFileStream);

    // Loop through the saved data objects.
    for(int i = 0; i < savedData.Levels.Count; i++)
    {
        System.Diagnostics.Debug.WriteLine("I am inside the loop and my index is" + i);
        // Get the data object in question.
        LevelData levelData = savedData.Levels[i];

        // Check to see if the index of the data object corresponds to the active level index.
        if (levelData.Index == mLevelIndex)
        {
            // Check that the attempts already saved is less.
            if (levelData.Attempts < mLevel.AttemptCounter)
                levelData.Attempts = mLevel.AttemptCounter;

            // Check that the 
            if (levelData.PercentComplete < 50)
                levelData.PercentComplete = 50;
        }
    }

    isolatedFileStream.Seek(0, SeekOrigin.Begin);
    serializer.Serialize(isolatedFileStream, savedData);
    isolatedFileStream.SetLength(isolatedFileStream.Position);
} 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top