正在将文件反序列化为列表C#

本文关键字:列表 反序列化 文件 | 更新日期: 2023-09-27 18:00:20

我正在尝试将包含对象的文件反序列化为对象列表但对于某些人来说,列表仅适用于对象这是我的代码:

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
        }
    }
}

这就是我正在序列化的类:

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;
        }
    }
}

当我运行它时,我得到列表的计数是1。

再跑一次,我得了2分。

运行1000次,您将获得2次。

我知道出了问题,所以请帮帮我。

正在将文件反序列化为列表C#

try中的代码是

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

上面代码中发生的情况是,在反序列化过程中,流位置指针被移动到文件的末尾。因此,当您向后序列化时,包含这两个对象的列表会附加在文件的末尾。

因此,新的文件结构类似于

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

因此,当您下次反序列化时,您将再次获得包含一个用户详细信息的列表。

要覆盖现有数据,请使用将流位置指针重置为文件的开头

ToStream.Seek(0, SeekOrigin.Begin);

因此,您的try块看起来像

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

问题是您正在用一个对象反序列化第一个列表,添加该项并将新列表附加到文件中。下次打开/读取文件时,您将再次读取第一个列表。

您需要做的就是在将新列表序列化到文件之前简单地倒带FileStream;

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