2013-12-16 2 views
0

게임을 만들고 있는데 게임 데이터를 저장하고 있습니다. 데이터는 단순히 bool, ints 및 float의 몇 가지 목록입니다.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는 정적이므로 두 개 이상의 스레드에서 this를 호출 할 수 있습니까? 파일 스트림에 쓰는 것은 serializer가 수행하는 것처럼 스레드로부터 안전하지 않습니다. – crad

+0

어떻게하면 하나의 스레드 만 사용하고 있는지 확인할 수 있습니까? –

+1

스레드 안전 파일 쓰기를 수행하는 데는 몇 가지 방법이 있습니다. 이제는 문제가 무엇인지 알았으므로 C#에서 스레드 안전 파일 작성에 대한 많은 답을 찾을 수 있습니다. 만약 당신이 그것을 해결할 수 없다면 더 많은 코드로 편집하십시오. – crad

답변

1

SaveLevelStats는 정적이므로 둘 이상의 스레드에서 this를 호출 할 수 있습니까?

파일 스트림에 쓰는 것은 serializer가 수행하는 것처럼 스레드로부터 안전하지 않습니다.

가장 간단한 해결책은 파일을 읽고 쓸 때 잠금을 사용하는 것입니다. 여러 스레드에서 계속 읽고 쓰는 경우주의하십시오.

+0

내 방법을 잠그고 자 노력 중입니다. 어떻게하면 내 방법이 어떻게 보이는지 보여줄 수 있습니까? –

+1

다음은 좋은 잠금 실행 http : // stackoverflow에 대한 좋은 토론입니다.com/questions/1330507/best-c-sharp-multi-threaded-threadsafe-read-write-locking은 Joseph Kingry의 대답을 확인합니다. – crad

관련 문제