使用序列化在窗体间传递数据时重复写入无法读取新数据的问题
问题原因分析
你遇到的核心问题是写入和读取序列化数据的逻辑不匹配:
- 写入时使用
FileMode.Append,每次将完整的VirtualAppointments列表序列化后追加到文件末尾,导致文件中存在多个独立的序列化列表对象。 - 读取时仅调用一次
Deserialize,只能获取文件中第一个序列化的列表,后续追加的列表数据完全被忽略。
两种解决方案
方案一:覆盖写入(推荐)
直接每次写入时覆盖整个文件,保存最新的完整列表,这样读取时只需一次反序列化就能拿到所有数据,逻辑更简洁高效。
修改写入代码:
VirtualAppointments.Add(vir1.ToString()); // 使用using自动释放文件流资源,替代手动Close using (FileStream outFile = new FileStream("VirtualAppointments.dat", FileMode.Create, FileAccess.Write)) { BinaryFormatter bFormatter = new BinaryFormatter(); bFormatter.Serialize(outFile, VirtualAppointments); } ViewAppointments viewAppointments = new ViewAppointments(); this.Close();
读取代码无需修改,保持原逻辑即可——因为文件中始终只有一个完整的序列化列表。
方案二:读取所有序列化对象(适配追加写入场景)
如果必须保留Append写入的逻辑,读取时需要循环调用Deserialize,直到文件流读取到末尾,再将所有读取到的列表内容合并。
修改读取代码中VirtualAppointments.dat的读取部分(InPersonAppointments.dat同理):
lstViewAppointments.Items.Clear(); BinaryFormatter bFormater = new BinaryFormatter(); // 处理InPersonAppointments using (FileStream inFile = new FileStream("InPersonAppointments.dat", FileMode.Open, FileAccess.Read)) { InPersonAppointmentsForDisplay = new List<string>(); // 循环读取所有序列化的列表对象 while (inFile.Position < inFile.Length) { var tempList = (List<string>)bFormater.Deserialize(inFile); InPersonAppointmentsForDisplay.AddRange(tempList); } } foreach (String s in InPersonAppointmentsForDisplay) { lstViewAppointments.Items.Add(s); } // 处理VirtualAppointments using (FileStream inFile = new FileStream("VirtualAppointments.dat", FileMode.Open, FileAccess.Read)) { VirtualAppointmentsForDisplay = new List<string>(); while (inFile.Position < inFile.Length) { var tempList = (List<string>)bFormater.Deserialize(inFile); VirtualAppointmentsForDisplay.AddRange(tempList); } } foreach (String s in VirtualAppointmentsForDisplay) { lstViewAppointments.Items.Add(s); }
额外提示
BinaryFormatter在.NET Core 3.0及以上版本已被标记为过时,存在安全风险。如果是新项目,建议使用System.Text.Json、Newtonsoft.Json或Protobuf等更安全、高效的序列化方案。
内容的提问来源于stack exchange,提问作者Tuffax
相关产品推荐
相关产品推荐

