2016-07-24 3 views
3

사용자 정보를 저장하기 위해 파일에 저장되는 User 클래스가있는 프로그램을 작성했습니다. 그러나 여러 다른 사용자가있을 수 있으므로 파일을 단일 사용자로 저장하는 대신 사용자 목록입니다. 이것은 XNA에 있으므로 게임이기는하지만 실제로는 사물에 영향을주지 않아야합니다. 사용자는 동전, 스킨, 인벤토리, 사용자 이름, 암호 (있는 경우) 및 hasPassword bool을가집니다. 사용자가 동전을 가지고 있기 때문에 편집 가능한 텍스트 파일이 아니기 때문에 바이너리 파일로 저장했습니다. 필자는 목록에 여러 사용자를 저장하려고 시도 할 때까지 일부 코드를 작성하고 테스트했으며 모든 것이 훌륭하고 훌륭했습니다. 어떤 이유로 두 번째 사용자를 저장하고 List에서 읽을 때마다 목록에는 하나의 개체 (첫 번째 사용자) 만있었습니다. 나는에보고C# : 이진 파일로 목록 작성 및 읽기

User test = new User("Bob", 0, "skin1", Content) 
test.SerializeUser(); 

: 여기

[Serializable] 
class User 
{ 
    #region Fields & Properties 

    public string Username = ""; 
    public string Password = ""; 
    public bool HasPassword = false; 

    public int Coins = 0; 
    public List<Achievement> AchievementsCompleted = new List<Achievement>(); 
    public List<InventoryItem> Inventory = new List<InventoryItem>(); 
    public List<string> Skins = new List<string>(); 

    public string CurrentSkinAsset { get; set; } 

    const int SPACING = 10; 

    const string FILE_PATH = "Users.bin"; 

    #endregion 

    #region Constructors 

    public User(string username, int coins, string skinPath, ContentManager content) 
    { 
     Username = username; 
     CurrentSkinAsset = skinPath; 
    } 
    public User(string username, string password, int coins, string skinPath, ContentManager content) 
     : this(username, coins, skinPath, content) 
    { 
     HasPassword = true; 
     Password = password; 
    } 

    #endregion 

    #region Public Methods 

    public static List<User> LoadUsers() 
    { 
     FileStream fileStream = null; 
     List<User> returnList = null; 
     try 
     { 
      if (File.Exists(FILE_PATH)) 
      { 
       fileStream = new FileStream(FILE_PATH, FileMode.Open, FileAccess.Read); 
       BinaryFormatter deserializer = new BinaryFormatter(); 
       returnList = (List<User>)deserializer.Deserialize(fileStream); 
      } 
      else 
      { 
       fileStream = File.Create(FILE_PATH); 
       List<User> users = new List<User>(); 
       BinaryFormatter serializer = new BinaryFormatter(); 
       serializer.Serialize(fileStream, users); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("There's been an error. Here is the message: " + e.Message); 
     } 
     finally 
     { 
      if (fileStream != null) 
      { 
       fileStream.Close(); 
      } 
     } 

     return returnList; 
    } 

    public void SerializeUser() 
    { 
     // Also works 
     FileStream fileStream = null; 
     List<User> users; 
     BinaryFormatter binaryFormatter = new BinaryFormatter(); 
     try 
     { 
      if (File.Exists(FILE_PATH)) 
      { 
       fileStream = File.Open(FILE_PATH, FileMode.Open); 
       //fileStream = new FileStream(FILE_PATH, FileMode.Open, FileAccess.ReadWrite); 
       users = (List<User>)binaryFormatter.Deserialize(fileStream); 
      } 
      else 
      { 
       fileStream = File.Create(FILE_PATH); 
       users = new List<User>(); 
      } 

      for (int i = 0; i < users.Count; i++) 
      { 
       if (users[i].Username.ToLower() == this.Username.ToLower()) 
       { 
        users.Remove(users[i]); 
       } 
      } 
      users.Add(this); 
      binaryFormatter.Serialize(fileStream, users); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("There's been an error. Here is the message: " + e.Message); 
     } 
     finally 
     { 
      if (fileStream != null) 
      { 
       fileStream.Close(); 
      } 
     } 
    } 

    #endregion 
} 

합니다 (GAME1 LoadContent 방법에서) 내가 쓴 테스트 코드입니다 : 자, 내가 쉽게이 이해할 수 있도록하기 위해 코드와 예제를 제공합니다 Debug 폴더를 열고 "Users.bin"이라는 새 파일을 찾았습니다. 예상대로 임의의 문자가 잔뜩 있습니다. 테스트의 사용자 이름 매개 변수를 "Bob"에서 "Joe"로 변경했습니다. 그러면 새 사용자가 추가됩니다.

List<User> testList = User.LoadUsers(); 

내가 코드의 다음 줄에 중단 점을 삽입하고, testList 맴돌고 있지만에만 표시 사용자가 밥, 그리고 조 :하지만 ... 여기


는 사용자가 읽을 수있는 코드이다 존재하지 않았다. 어떤 아이디어? 또한 : 나는 13 세입니다. 내가 오랫동안 프로그래밍하지 않았기 때문에 내가 사용하는 모든 용어를 이해하지 못할 수도 있습니다. 미리 감사드립니다.

+1

질문과 관련이 없지만 [MonoGame] (http://www.monogame.net/)을 살펴볼 수 있습니다. Microsoft는 몇 년 전 XNA Framework 개발을 중단했지만 MonoGame은 XNA Framework 4의 적극적으로 개발 된 오픈 소스 구현입니다. XNA와 달리 Android, iOS, Linux, OS X, PS4 등의 플랫폼도 지원합니다. 행운을 비네! – hankide

+0

감사합니다. 생각 MonoGame은 Xna 등의 Mac 버전이었습니다. –

답변

3

문제는 당신이 사용자, 당신의 FileStream를 열고 목록에서 읽고있는 목록을 저장할 때 (현재 사용자를 대체 할), 다음 위치를 재설정하지 않고 FileStream에 새 목록을 저장하는 것입니다. 초기 읽기는 FileStream을 파일 끝으로 이동합니다. 저장하면 초기 목록 다음에 FileStream에 새 목록이 추가됩니다.

무엇 후 발생하는이처럼 보이는 파일이 있습니다 :

*start of file* 
List(User1) 
List(User1,User2) 
*end of file* 

당신이 그것을 읽을 때마다, 당신은 단지 초기 목록 있음을 얻고있다.

이 시도 : 그것은 가치가 무엇인지에 대한

 users.Add(this); 
     filStream.Position = 0; 
     binaryFormatter.Serialize(fileStream, users); 

, 이것은 절약과 사용자로드를 처리 할 수있는 매우 비효율적 인 방법입니다. 모든 사용자가 변경 될 때마다 전체 목록을 읽고 쓰는 것이 본질적입니다. 또한 스레드 안전성이 없습니다 (다중 동시 업데이트가있는 멀티 플레이어 게임 인 경우 의미에 따라 사용자 파일이 손상되거나 업데이트가 발생할 수 있음). 일반 파일이 아닌 적절한 데이터베이스를 조사하는 것이 좋습니다.

+0

답해 주셔서 감사합니다. 이제 작동합니다.또한 조언을 주셔서 감사합니다; 데이터베이스를 사용하고 싶지만 아직 그 수준이 아닙니다. –

관련 문제