Question

I'm trying to deserialize a file which contains objects into a list of objects but for some how the list takes to objects only here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            user lastuser = new user("First name", "Last name", "Username", "Password");
            FileStream ToStream = new FileStream("UsersDB.txt", FileMode.OpenOrCreate);
            BinaryFormatter Ser = new BinaryFormatter();
            List<user> ToUsers = new List<user>();

            try
            {
                ToUsers = (List<user>)Ser.Deserialize(ToStream); // this is to deserialize everything in the file to the list
                ToUsers.Add(lastuser); // here we are adding our object (which is lastuser) to the list
                Ser.Serialize(ToStream, ToUsers); // here we are serializing the list back to the file
            }
            catch (System.Runtime.Serialization.SerializationException)
            {//this is to catch the exception if the file was empty and there is nth to deserialize to the list
                ToUsers.Add(lastuser);
                Ser.Serialize(ToStream, ToUsers);
            }
            ToStream.Close();

            Console.WriteLine("ToUsers objects : " + ToUsers.Count());
            // this is to see how many objects does the list have
        }
    }
}

and this is the class I'm serializing:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;

namespace Test
{
    [Serializable]
    class user
    {
        private string Fname, Lname, Username, Password;

        public user()
        { }

        public user(string Fname, string Lname, string Username, string Password)
        {
            this.Fname = Fname;
            this.Lname = Lname;
            this.Username = Username;
            this.Password = Password;
        }

        public string GetUsername()
        {
            return Username;
        }

    }
}

When I run it, I get the count of list is 1.

Run it again I get it 2.

Run it 1000 times and you will get 2.

I know there is something wrong so please help me.

Was it helpful?

Solution

Your code within try is

  try
  {
      ToUsers = (List<user>)Ser.Deserialize(ToStream);
      ToUsers.Add(lastuser);
      Ser.Serialize(ToStream, ToUsers);
  }

what is happening in the above code is, during de-serialization, the stream position pointer is moved to the end of the file. So when you serialize back, the list containing the two objects is appended at the end of the file.

Hence, the new file structure is like

 +---------------------+-----------------------------------------------------+
 | List (1 user info)  |    List (2 user's info)                             |
 +---------------------+-----------------------------------------------------+

So, when you de-serialize the next time, you again get the list containing one user's details.

To overwrite the existing data, reset the stream position pointer to the beginning of the file using

ToStream.Seek(0, SeekOrigin.Begin);

Hence, your try block would look like

  try
  {
      ToUsers = (List<user>)Ser.Deserialize(ToStream);
      ToStream.Seek(0, SeekOrigin.Begin);

      ToUsers.Add(lastuser);
      Ser.Serialize(ToStream, ToUsers);
  }

OTHER TIPS

The problem is that you're deserializing the first list with one object, adding the item and appending the new list to the file. Next time you open/read the file, you'll read the first list again.

What you need to do is simply rewind the FileStream before serializing the new list to the file;

ToUsers = (List<user>)Ser.Deserialize(ToStream);
ToUsers.Add(lastuser); // here we are adding our object (which is lastuser) to the list
ToStream.Seek(0, SeekOrigin.Begin);
Ser.Serialize(ToStream, ToUsers); // here we are serializing the list back to the file
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top