【问题标题】:Deserializing a file into List C#将文件反序列化为 List C#
【发布时间】:2014-04-27 17:24:08
【问题描述】:

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

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# list serialization deserialization


    【解决方案1】:

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

    【讨论】:

    • 哦,非常感谢,我明白了:)...好吧,我还有一个问题...如果我使用文件流打开任何文件,是否有指针指向它的结尾?
    • ToStream.Seek(0, SeekOrigin.End);
    【解决方案2】:

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

    您需要做的只是在将新列表序列化到文件之前倒回 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
    

    【讨论】:

      猜你喜欢
      • 2015-06-07
      • 1970-01-01
      • 2018-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      相关资源
      最近更新 更多