2013-11-29 2 views
0

Я пытаюсь создать метод для сохранения некоторых базовых данных в XML-файле. Я могу создать файл и сериализовать его, но когда я пытаюсь редактировать информацию, в следующий раз, когда я попытаюсь десериализовать это, вы получите исключение - вот ошибка в документе XML (10, 10).десериализация файла xml и добавление данных без разрушения целостности

Так ясно, когда я пытаюсь сериализовать файл после первого раза, я делаю его таким образом, чтобы он испортил целостность. Я не могу найти то, что разрушает файл, поэтому задался вопросом, может ли кто-нибудь предложить какие-то советы - правильно ли я переписываю данные?

Вот код, который вызывает проблемы и типы данных приведены ниже:

#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; 
} 
+0

Я отредактированный свой титул. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –

ответ

1

Вы пишете isolatedFileStream после прочтения содержимого XML из него. Таким образом, добавление новой версии в файл.

Вы должны искать в начале файла, записывать новый контент и обрезать файл.

Или просто закройте поток и откройте другой с помощью 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); 
} 
+0

Хорошо, что останавливает ошибку :-) –

+0

Могу ли я спросить, почему вы называете метод заданной длины? –

+0

Новый XML-файл может быть короче старого. После записи в поток нам нужно удалить что-либо за последний написанный байт. Это то, что делает SetLength. – Reda

Смежные вопросы