反序列化xml文件并添加数据而不破坏完整性

时间:2013-11-29 16:37:51

标签: c# xml xml-serialization xmlserializer monogame

我正在尝试创建一种方法来将一些基本数据保存到xml文件中。我可以创建该文件并对其进行序列化,但是当我尝试编辑信息时,下次我尝试反序列化时抛出异常 - 这是XML文档中的错误(10,10)。

很明显,当我第一次尝试序列化文件后,我这样做会弄乱完整性。我无法找到破坏文件的内容,所以想知道是否有人可以提供一些建议 - 我是否正确地重写数据?

以下是导致问题的代码,数据类型如下:

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

数据

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

1 个答案:

答案 0 :(得分:1)

您在阅读了XML内容之后写信给isolatedFileStream。因此,将新版本附加到文件中。

您应该寻找文件的开头,编写新内容并截断文件。

或者只关闭该流并使用FileMode.Create打开另一个。

以下是我将如何实施第一个解决方案:

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