2013-12-16 168 views
0

我正在製作遊戲,並且正在序列化保存遊戲數據,數據僅僅是一些bools,整數和浮點數的列表。在XML文檔中存在錯誤(保持添加垃圾到文件結尾)

但是,當數據嘗試保存或加載「XML文檔中存在錯誤」時,大約有50%的時間出現錯誤。該錯誤始終位於文件的末尾,即使它已更改大小或我添加了其他變量。

看來XML數據的最後一部分被複制了兩次。該XML的最後一行應爲:

</LevelStats> 

但是當錯誤發生時,經常讀

</LevelStats>> 

或者

</LevelStats>tats> 

或複製的最後一行的其他一些小部分。

這裏是我的序列化類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Serialization; 
using Microsoft.Xna.Framework.Storage; 
using System.IO; 

namespace Jetpack.Classes 
{ 
    [Serializable] 
    public struct LevelStats 
    { 
     // Player Bests 
     public List<float?> fTimeList; 
     public List<int?> iScoreList; 
     public List<int?> iFuelList; 

     // Time 
     public List<bool> bBronzeTimeList; 
     public List<bool> bSilverTimeList; 
     public List<bool> bGoldTimeList; 

     // Score 
     public List<bool> bBronzeScoreList; 
     public List<bool> bSilverScoreList; 
     public List<bool> bGoldScoreList; 

     // Fuel 
     public List<bool> bBronzeFuelList; 
     public List<bool> bSilverFuelList; 
     public List<bool> bGoldFuelList; 

     // Level Complete 
     public List<bool> bIsLevelComplete; 
    } 
} 

這裏是我保存的加載數據的方法:

區域保存&負載水平統計

public static void SaveLevelStats(LevelStats levelStats, string filename) 
    { 
     // Get the path of the save game 
     string fullpath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename); 

     // 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(LevelStats)); 
      serializer.Serialize(stream, levelStats); 
     } 
     finally 
     { 
      // Close the file 
      stream.Close(); 
     } 
    } 

    public static LevelStats LoadLevelStats(string filename) 
    { 
     LevelStats levelStats; 

     // Get the path of the save game 
     string fullpath = System.IO.Path.Combine((Directory.GetCurrentDirectory()), filename); 

     // Open the file 
     FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate, 
     FileAccess.Read); 
     try 
     { 
      // Read the data from the file 
      XmlSerializer serializer = new XmlSerializer(typeof(LevelStats)); 
      levelStats = (LevelStats)serializer.Deserialize(stream); 
     } 
     finally 
     { 
      // Close the file 
      stream.Close(); 
     } 

     return (levelStats); 
    } 

    #endregion 

最後這裏是XML文件

<?xml version="1.0"?> 
<LevelStats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <fTimeList> 
    <float xsi:nil="true" /> 
    <float>19.016552</float> 
    <float>9.766692</float> 
    <float>62.9992142</float> 
    <float>11.6666632</float> 
    <float xsi:nil="true" /> 
    <float xsi:nil="true" /> 
    <float xsi:nil="true" /> 
    <float xsi:nil="true" /> 
    <float xsi:nil="true" /> 
    <float xsi:nil="true" /> 
    </fTimeList> 
    <iScoreList> 
    <int xsi:nil="true" /> 
    <int>690</int> 
    <int>390</int> 
    <int>690</int> 
    <int>200</int> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    </iScoreList> 
    <iFuelList> 
    <int xsi:nil="true" /> 
    <int>293</int> 
    <int>206</int> 
    <int>1134</int> 
    <int>202</int> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    <int xsi:nil="true" /> 
    </iFuelList> 
    <bBronzeTimeList> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bBronzeTimeList> 
    <bSilverTimeList> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bSilverTimeList> 
    <bGoldTimeList> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bGoldTimeList> 
    <bBronzeScoreList> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bBronzeScoreList> 
    <bSilverScoreList> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bSilverScoreList> 
    <bGoldScoreList> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bGoldScoreList> 
    <bBronzeFuelList> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bBronzeFuelList> 
    <bSilverFuelList> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bSilverFuelList> 
    <bGoldFuelList> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bGoldFuelList> 
    <bIsLevelComplete> 
    <boolean>false</boolean> 
    <boolean>true</boolean> 
    <boolean>true</boolean> 
    <boolean>true</boolean> 
    <boolean>true</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    <boolean>false</boolean> 
    </bIsLevelComplete> 
</LevelStats> 

任何幫助您可以提供我將不勝感激。

謝謝。

+1

由於SaveLevelStats是靜態的,是否可以從多個線程中調用它? 正如序列化程序正在寫入文件流一樣,它不是線程安全的。 – crad

+0

我將如何去確保它只使用單個線程? –

+1

有幾種方法可以執行線程安全文件寫入。現在你知道這個問題可能是什麼,你可以在這裏找到很多關於在c#中編寫線程安全文件的答案。如果無法解決問題,也許可以編輯更多的代碼。 – crad

回答

1

由於SaveLevelStats是靜態的,您是否有可能從多個線程中調用它?

正如串行器所做的那樣寫入文件流不是線程安全的。

最簡單的解決方案是在讀寫文件時使用鎖。如果您仍在閱讀和/或從多個線程寫入,請小心。

+0

我正在努力鎖定我的方法,你能證明它是如何看待我的方法嗎? –

+1

下面是一個很好的鎖定實踐http:// stackoverflow的討論。com/questions/1330507/best-c-sharp-solution-for-multithreaded-threadsafe-read-write-locking查看Joseph Kingry的答案 – crad

相關問題