1

Saving or reading a file, what is wrong?

This creates empty files.

I'm confused, please tell me how to do it properly. As you can see I'm trying to save a class and then read an array of them back.

public void savePlayers()
{
    string path = @"scores.dat";

    if (File.Exists(path))
    {
        File.Delete(path);
    }

    try
    {
        using (FileStream fs = File.Create(path))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(fs, player.players);
            fs.Close();
        }
    }
    catch
    {
        MessageBox.Show("Failed to save data", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

public void readPlayers()
{
    string path = @"scores.dat";

    player.players.Clear();
    try
    {
        using (FileStream fs = File.OpenRead(path))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            player.players.Add((Player)formatter.Deserialize(fs));
            fs.Close();
        }
    }
    catch
    {
        MessageBox.Show("Failed to read stats file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
GSerg
  • 76,472
  • 17
  • 159
  • 346
  • FYI `fs.Close();` is unnecessary. Wrapping the stream in a `using` statement takes care of that for you. To address your question, it's probably saving empty because you're saving empty. I'm assuming `formatter` is of type `XmlSerializer`? Can you share what that is? Can you share what `players.players` is and show how you're populating it? If you encounter an exception, your file would be created but left empty. Are you getting an exception? Also you need to show you're calling these methods. – tnw Dec 10 '14 at 18:43
  • 1
    @tnw: `formatter` is of type `BinaryFormatter`, not `XmlFormatter`... – Sjips Dec 10 '14 at 18:47
  • @Sjips Woops, not sure how I missed that. Thanks. The rest of my comment still stands :) – tnw Dec 10 '14 at 18:48

1 Answers1

1

You are saving a player.players collection and you are trying to load a single Player (player.players.Add((Player)formatter.Deserialize(fs));). This is not correct.

It depends where you have to fix this on the loading side (Deserialize) or at the saving side (Serialize).

// Saving
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, player.players.Count); // or Count(), Length, depends on your list, collection,...
for each (Player pl in player.players)
{
  formatter.Serialize(fs, pl);
}
fs.Close();

// Loading
BinaryFormatter formatter = new BinaryFormatter();
int count = (Int32) formatter.Deserialize(fs);
for (int i = 0; i < count; i++)
{
  player.players.Add((Player)formatter.Deserialize(fs));
}
fs.Close();

And Player class has to be marked as [Serializable], please check if it has this attribute.

Sjips
  • 1,248
  • 2
  • 11
  • 22
  • I think you have to save the collection count first, and then serialize each item in your collection. On the loading side, first deserialize the count, and use that number in a for-loop to deserialize the items and and add them to your collection. I will try to add example... – Sjips Dec 10 '14 at 18:52
  • And has your `Player` class a `[Serializable]` attribute? – Sjips Dec 10 '14 at 19:03