程序在第三次编译后擦除序列化数据

时间:2016-01-06 14:48:52

标签: c# serialization

问题

启动1:本机启动,没有问题,退出时,保存当前状态

启动2:在退出时加载保存的数据,没有问题,保存当前状态

启动3:由于某种原因返回本机启动,其中一切都处于默认位置

代码

private void Form1_Load(object sender, EventArgs e)
{
GenerateTestData(); //use method to create data upon load
DisplayEmployeeData(employees, supervisors); //use method to display data upon load
RedundancyCheck();
}



GenerateTestData Method 

public void GenerateTestData()
    {
        Employee e1 = new Employee(MemberJob.Employee, "Name1", MemberSkills.CPlus | MemberSkills.CSharp, false);
        Employee e2 = new Employee(MemberJob.Employee, "Name2", MemberSkills.CSharp | MemberSkills.Oracle | MemberSkills.CPlus, false);
        Employee e3 = new Employee(MemberJob.Employee, "Name3", MemberSkills.CSharp | MemberSkills.Javascript, false);
        Supervisor e4 = new Supervisor(MemberJob.Supervisor, "Name4", false);
        Supervisor e5 = new Supervisor(MemberJob.Supervisor, "Name5", false);
        employees.Add(e1);
        employees.Add(e2);
        employees.Add(e3);
        supervisors.Add(e4);
        supervisors.Add(e5);
    }
RedundancyCheck method

private void RedundancyCheck()
{
bool _success = false;
BinaryFormatter bFormatter = new BinaryFormatter();
try
{
using (FileStream fs = new FileStream(FILENAME, FileMode.Open))
{
_success = true;
}
if (_success)
{
LoadData();
}
}
catch
{
if (!_success)
{
MessageBox.Show("There has been a problem with the main save, resorting to the backup copy!");
using (FileStream fs = new FileStream("BackupMembers.dat", FileMode.Open, FileAccess.Read))
{
List<Employee> employees = (List<Employee>)bFormatter.Deserialize(fs);
List<Supervisor> supervisors = (List<Supervisor>)bFormatter.Deserialize(fs);
ClearTable();
DisplayEmployeeData(employees, supervisors);
}
}
}
}

当表单关闭时,它运行SaveData方法

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

所以说比如说,Name1忙于工作,第二次加载它后显示正常,然后当我第三次加载它时,它只显示TestData显示的内容

更新!

事实证明,SaveData文件在第二次关闭时保存默认值。

首次关闭的代码

Busy = true
EmployeeName = Name1
EmployeeWorkload = "Test"
ShiftsLeft = 2

第二次关闭的代码

Busy = false
EmployeeName = "Name1"
EmployeeWorkload = null
ShiftsLeft = 0

1 个答案:

答案 0 :(得分:3)

这是问题

using (FileStream fs = new FileStream(FILENAME, FileMode.OpenOrCreate))

FileMode.OpenOrCreate不会截断现有文件,因此您最终会得到错误的数据。

改为使用FileMode.Create,根据documentation

  

指定操作系统应创建新文件。如果该文件已存在,则将被覆盖。 FileMode.Create等同于请求如果文件不存在,则使用CreateNew;否则,请使用截断。

编辑:在您的表单中,您有以下字段定义

private List<Employee> employees; //create a generic list of employees
private List<Supervisor> supervisors;

但是,在某些方法中,您可以使用类似

的内容
List<Employee> employees = ...
List<Supervisor> supervisors = 

创建局部变量,表单字段保持默认状态。要解决这个问题,请在代码中查找使用此类本地的位置,并使用表单变量,而不是像这样

employees = ...
supervisors = ...