You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#从.dat文件反序列化列表并显示到文本框的问题

问题分析与解决方案

问题根源

你当前的读取问题源于写入逻辑:每次保存时都创建一个仅含单条数据的List<InPerson>,然后将整个List序列化后追加到文件中。这导致.dat文件里存储了多个独立的序列化List<InPerson>对象块,而非一个包含所有数据的完整List。而你读取时仅调用了一次Deserialize,自然只能拿到文件中的第一个List,后续的多个List对象完全没被处理。

另外必须注意:InPerson类必须标记[Serializable]特性,否则BinaryFormatter无法完成序列化/反序列化操作(你的代码中未体现这一点,这是必要前提)。


解决方案1:适配原有写入逻辑的读取代码

读取时循环调用Deserialize,直到文件流到达末尾(此时会抛出EndOfStreamException,捕获该异常即可终止循环):

第一步:给InPerson类添加序列化特性

[Serializable]
public class InPerson
{
    public int iId;
    public string sDate;
    public string sTime;
    public string sDuration;
    public string sPatientname;
    public string sPhonenumber;
    public string sDoctorid;
    public string sRoomnumber;
    public string sNurseid;

    // 你的构造函数保持不变
    public InPerson(int iId, string sDate, string sTime, string sDuration, string sPatientname, string 
    sPhonenumber, string sDoctorid, string sRoomnumber, string sNurseid)
    {
        this.iId = iId;
        this.sDate = sDate;
        this.sTime = sTime;
        this.sDuration = sDuration;
        this.sPatientname = sPatientname;
        this.sPhonenumber = sPhonenumber;
        this.sDoctorid = sDoctorid;
        this.sRoomnumber = sRoomnumber;
        this.sNurseid = sNurseid;
    }

    // 你的ToString方法保持不变
    public override string ToString()
    {
        return "In Person Apppointment:  " + iId + System.Environment.NewLine +
        "Date:  " + sDate + System.Environment.NewLine +
        "Time:  " + sTime + System.Environment.NewLine +
        "Duration:  " + sDuration + System.Environment.NewLine +
        "Patients Name: " + sPatientname + System.Environment.NewLine +
        "Patients Number: " + sPhonenumber + System.Environment.NewLine +
        "Doctors ID:  " + sDoctorid + System.Environment.NewLine +
        "Room Number: " + sRoomnumber + System.Environment.NewLine +
        "Nurse id:  " + sNurseid + System.Environment.NewLine;
    }
}

第二步:修正读取代码

const string filename = "appointments.dat";
BinaryFormatter bFormatter = new BinaryFormatter();
txtBookings.Text = ""; // 先清空文本框

using (FileStream inFile = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
    try
    {
        while (true)
        {
            // 读取文件中的下一个List<InPerson>对象
            List<InPerson> currentList = (List<InPerson>)bFormatter.Deserialize(inFile);
            // 遍历当前List的所有元素并追加到文本框
            foreach (InPerson a in currentList)
            {
                txtBookings.Text += a.ToString() + "------------------------" + System.Environment.NewLine;
            }
        }
    }
    catch (EndOfStreamException)
    {
        // 文件读取完毕,终止循环
    }
}

解决方案2:优化写入逻辑(更合理的方式)

每次写入时先读取文件中已有的所有数据,合并成一个完整的List后再整体序列化覆盖文件,这样读取时只需一次反序列化即可获取所有数据:

优化后的写入代码

const string filename = "appointments.dat";
List<InPerson> allInPersonList = new List<InPerson>();

// 读取已有的预约数据(如果文件存在)
if (File.Exists(filename))
{
    using (FileStream inFile = new FileStream(filename, FileMode.Open, FileAccess.Read))
    {
        BinaryFormatter bFormatterRead = new BinaryFormatter();
        try
        {
            while (true)
            {
                var existingList = (List<InPerson>)bFormatterRead.Deserialize(inFile);
                allInPersonList.AddRange(existingList);
            }
        }
        catch (EndOfStreamException)
        {
            // 读取完成
        }
    }
}

// 添加新的预约
InPerson newInPersonApp = new InPerson(
    Convert.ToInt32(txtID.Text), 
    dateTimePickerBooking.Text, 
    txtTime.Text, 
    txtDuration.Text, 
    txtPatientName.Text, 
    txtPhoneNumber.Text, 
    txtDoctorID.Text, 
    txtRoomAllocated.Text, 
    txtNurseID.Text
);
allInPersonList.Add(newInPersonApp);

// 覆盖写入完整的List
using (FileStream outFile = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
    BinaryFormatter bFormatterWrite = new BinaryFormatter();
    bFormatterWrite.Serialize(outFile, allInPersonList);
}

对应简化的读取代码

const string filename = "appointments.dat";
txtBookings.Text = "";

if (File.Exists(filename))
{
    using (FileStream inFile = new FileStream(filename, FileMode.Open, FileAccess.Read))
    {
        BinaryFormatter bFormatter = new BinaryFormatter();
        List<InPerson> allList = (List<InPerson>)bFormatter.Deserialize(inFile);
        foreach (InPerson a in allList)
        {
            txtBookings.Text += a.ToString() + "------------------------" + System.Environment.NewLine;
        }
    }
}

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:40:21