2016-07-24 15 views
3

ユーザークラスを持つプログラムを作成しました。これはファイルに保存され、ユーザー情報を格納します。ただし、複数の異なるユーザーが存在する可能性があるため、ファイルを単一のユーザーとして保存するのではなく、ユーザーの一覧です。これはXNAであり、したがってゲームですが、実際には物事に影響を与えるべきではありません。ユーザーには、コイン、スキン、インベントリ、ユーザー名、パスワード(あれば)、hasPassword boolがあります。ユーザーはコインを持っているので、これを編集可能なテキストファイルにしたくないので、バイナリファイルとして保存しました。私はリストに複数のユーザーを保存しようとするまで、いくつかのコードを書いて、それをテストし、すべてうまくやっていました。何らかの理由で、2番目のユーザーを保存してリストを読み込むたびに、リストには1つのオブジェクト(最初のユーザー)しかありませんでした。私が見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はMac版のXnaなどでした。 –

答えて

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

あなたの答えをありがとう。それは今働く。また、アドバイスをいただきありがとうございます。私はデータベースを使いたいですが、まだそのレベルにはいません。 –

関連する問題