如何反序列化,然后将数据放入表单

本文关键字:数据 表单 然后 反序列化 | 更新日期: 2023-09-27 18:28:04

目标

我目前有一个保存信息的有效方法

然后,我希望程序在退出后单击"加载"按钮时加载保存的状态。

然后我希望程序在适当的位置显示数据

在表单中,我有两个DataGridView,一个用于员工,另一个用于主管。

=============================================

方法

我已经将两个通用列表序列化为.dat文件

BinaryFormatter bFormatter = new BinaryFormatter();    
using (FileStream fs = new FileStream(FILENAME, FileMode.OpenOrCreate))
{
  bFormatter.Serialize(fs, employees);
  bFormatter.Serialize(fs, supervisors);
}

到目前为止,在.dat文件中,我有3名员工和2名主管,我不确定如何提取信息并将其放入适当的中

列表如下:

List<Employee> employees = new List<Employee>();
List<Supervisor> supervisors = new List<Supervisor>();
Employee e1 = new Employee(MemberJob.Employee, "Name", MemberSkills.CPlus | MemberSkills.CSharp, false);
Supervisor s1 = new Supervisor(MemberJob.Supervisor, "Another name", false); 
employees.Add(e1);
supervisors.Add(s1);

================================================

尝试

我在互联网和Stackoverflow上做了大量的浏览,但主要是它与我的上下文无关,或者他们使用的是我不想使用的XML格式。

我认为这只是复制serialize方法并将bFormatter.Serialize(fs, employees);更改为bFormatter.Deserialize(fs, employees);的情况,但我不知道在反序列化列表后该怎么办。

 BinaryFormatter bFormatter = new BinaryFormatter();
 FileStream fs = File.Open(FILENAME, FileMode.Open);
 object obj = bFormatter.Deserialize(fs);

然后,该对象会带回我需要的数据,但我无法将object obj数据放入可用的格式,它被卡在object obj中。如果可能的话,我想尝试将其放回Employee list

如何反序列化,然后将数据放入表单

我送给你的圣诞礼物。希望能有所帮助。:)
namespace WpfApplication3
{
    public partial class App : Application
    {
        string path = @"C:'Users'xxx'Desktop'myFile.dat";
        public App()
        {
            InitializeComponent();
            //Test
            List<Employee> eList = new List<Employee>();
            eList.Add(new Employee("aaa"));
            eList.Add(new Employee("bbb"));
            List<Supervisor> sList = new List<Supervisor>();
            sList.Add(new Supervisor("ccc"));
            sList.Add(new Supervisor("ddd"));
            SavedInfo savedInfo = new SavedInfo();
            savedInfo.employeeList = eList;
            savedInfo.supervisorList = sList;

            SaveToFile(savedInfo); //Save to file
            SavedInfo newSaveGame = LoadFromFile(); //Load from file
            foreach (var e in newSaveGame.employeeList)
                Console.WriteLine("Employee: " + e.name);
            foreach (var e in newSaveGame.supervisorList)
                Console.WriteLine("Supervisor: " + e.name);
        }
        public void SaveToFile(SavedInfo objectToSerialize)
        {
            Stream stream = File.Open(path, FileMode.Create);
            BinaryFormatter bFormatter = new BinaryFormatter();
            bFormatter.Serialize(stream, objectToSerialize);
            stream.Close();
        }
        public SavedInfo LoadFromFile()
        {
            if (!System.IO.File.Exists(path))
                return new SavedInfo();
            SavedInfo objectToSerialize;
            Stream stream = File.Open(path, FileMode.Open);
            BinaryFormatter bFormatter = new BinaryFormatter();
            objectToSerialize = (SavedInfo)bFormatter.Deserialize(stream);
            stream.Close();
            return objectToSerialize;
        }
    }
    [Serializable()]
    public class SavedInfo
    {
        public List<Employee> employeeList = new List<Employee>();
        public List<Supervisor> supervisorList = new List<Supervisor>();
    }
    [Serializable()]
    public class Employee
    {
        public string name = "";
        public Employee(string eName)
        {
            name = eName;
        }
    }
    [Serializable()]
    public class Supervisor
    {
        public string name = "";
        public Supervisor(string eName)
        {
            name = eName;
        }
    }
}

编辑:根据jdweng的评论进行编辑。我认为jdweng是对的。

与大多数其他序列化程序不同,BinaryFormatter记录被序列化对象的完整.Net类型元数据。正如您所注意到的,它还允许在二进制文件中按顺序写入多个对象。

因此,假设您知道二进制文件中应该出现的对象序列,您可以在流上多次调用Deserialize(fs),然后将返回的对象强制转换为您期望的对象:

var supervisors = (List<Supervisor>)bFormatter.Deserialize(fs);
var employees = (List<Employee>)bFormatter.Deserialize(fs);

话虽如此,您的SupervisorEmployee类中是否有相互直接引用的?例如,像这样的东西?

[Serializable]
public class Employee : Person
{
    public Supervisor Supervisor { get; set; }
}

如果是这样的话,您必须在对Serialize()的单个调用中序列化员工和主管列表,因为BinaryFormatter只保留对Serialize()Deserialize()的每个单个调用中的对象图关系。如果有单独的呼吁,相互关系就会消失。为了避免这个潜在的问题,您可以将列表打包在一个根对象中,例如List<object>:

var bFormatter = new BinaryFormatter();
var root = new List<object> { supervisors, employees };
bFormatter.Serialize(fs, root);

然后,要反序列化:

var bFormatter = new BinaryFormatter();
var root = (List<object>)bFormatter.Deserialize(fs);
var employees = root.OfType<IEnumerable<Employee>>().SelectMany(e => e).ToList();
var supervisors = root.OfType<IEnumerable<Supervisor>>().SelectMany(e => e).ToList();

顺便说一句,使用BinaryFormatter进行序列化可能不是长期保存数据的最佳选择。如果对类进行任何更改,则需要实现版本容忍序列化。另请参阅强命名是否会导致C#中的对象序列化出现问题?。BinaryFormatter完全基于文件中的类型信息来构造对象,这一事实可能会在反序列化不受信任的数据时引入安全风险。