有时 C# XmlSerializer Serialize(save) 错误,比预期更多的字符
Sometimes C# XmlSerializer Serialize(save) wrong, more characters than expect
通常你操作文件它运行良好,但有时文件会像这样出错..(结束额外部分“ConfigSetting>”),我所做的是打开、编辑并保存它。
<?xml version="1.0"?>
<SystemConfigSetting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" IsRuntime="true">
<ReportSchedulers>
<ReportScheduler ReportName="report1" FullreportName="report1" IsEnableAutosaveReport="true" Hour="14" Minute="50" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report2" FullreportName="report2" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report3" FullreportName="report3" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report4" FullreportName="report4" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report5" FullreportName="report5" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
</ReportSchedulers>
</SystemConfigSetting>ConfigSetting>
除结尾部分 ConfigSetting> 其他部分都是正确的,我尝试删除结尾多余的部分,配置文件将能够反序列化。
下面是我的代码。
保存系统配置:
public static bool SaveSystemConfig(SystemConfigSetting systemConfig)
{
try
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SystemConfigSetting));
using (FileStream fs = new FileStream(CONFIGFILEPATH), FileMode.Open))
{
xmlSerializer.Serialize(fs, systemConfig);
fs.Close();
}
return true;
}
catch (Exception ex)
{
return false;
}
}
系统配置设置:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace HZSpreadSheet.Model
{
[Serializable]
[XmlRoot]
public class SystemConfigSetting
{
private bool isRuntime = false;
private List<ReportScheduler> reportSchedulers = new List<ReportScheduler>();
[XmlAttribute]
public bool IsRuntime { get => isRuntime; set => isRuntime = value; }
[XmlArray]
[XmlArrayItem]
public List<ReportScheduler> ReportSchedulers { get => reportSchedulers; set => reportSchedulers = value; }
}
}
ReportScheduler:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace HZSpreadSheet.Model
{
public enum ReportSaveFrequency
{
Daily = 0,
Weekly = 1,
Monthly = 2,
Manually =3
}
public enum DayofWeek
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6
}
[XmlRoot]
public class ReportScheduler
{
private string abbr_reportName;
private string fullreportName;
private bool isEnableAutosaveReport = false;
private int hour = 0;
private int minute = 0;
private int second =0;
private DateTime lastUpdate;
private DayofWeek dayofWeek;
private ReportSaveFrequency reportSaveFrequency;
[XmlAttribute]
public string ReportName { get => abbr_reportName; set => abbr_reportName = value; }
[XmlAttribute]
public string FullreportName { get => fullreportName; set => fullreportName = value; }
[XmlAttribute]
public bool IsEnableAutosaveReport { get => isEnableAutosaveReport; set => isEnableAutosaveReport = value; }
[XmlAttribute]
public int Hour { get => hour; set => hour = value; }
[XmlAttribute]
public int Minute { get => minute; set => minute = value; }
[XmlAttribute]
public int Second { get => second; set => second = value; }
[XmlAttribute]
public ReportSaveFrequency ReportSaveFrequency { get => reportSaveFrequency; set => reportSaveFrequency = value; }
[XmlAttribute]
public DayofWeek DayofWeek { get => dayofWeek; set => dayofWeek = value; }
[XmlAttribute]
public DateTime LastUpdate { get => lastUpdate; set => lastUpdate = value; }
}
}
如果您覆盖一个文件(或类似的流)并用较短的数据覆盖一个更长的文件,而不截断它,就会发生这种情况。如果您打开现有文件以使用写入 (FileMode.Open
) 进行随机访问,它会假设您要编辑内容,但 not 会假设您只需要新位.您看到的是来自 old 负载的额外字节,这些字节不会自动删除。有两种截断方式:
- 打开文件时使用
FileMode.Create
,将文件初始化为零长度
- 写完后在
Stream
上使用 SetLength
,告诉它新的长度 - 例如 stream.SetLength(stream.Position);
通常你操作文件它运行良好,但有时文件会像这样出错..(结束额外部分“ConfigSetting>”),我所做的是打开、编辑并保存它。
<?xml version="1.0"?>
<SystemConfigSetting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" IsRuntime="true">
<ReportSchedulers>
<ReportScheduler ReportName="report1" FullreportName="report1" IsEnableAutosaveReport="true" Hour="14" Minute="50" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report2" FullreportName="report2" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report3" FullreportName="report3" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report4" FullreportName="report4" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
<ReportScheduler ReportName="report5" FullreportName="report5" IsEnableAutosaveReport="false" Hour="0" Minute="0" Second="0" ReportSave="Daily" DayofWeek="Sunday" LastUpdate="0001-01-01T00:00:00" />
</ReportSchedulers>
</SystemConfigSetting>ConfigSetting>
除结尾部分 ConfigSetting> 其他部分都是正确的,我尝试删除结尾多余的部分,配置文件将能够反序列化。
下面是我的代码。
保存系统配置:
public static bool SaveSystemConfig(SystemConfigSetting systemConfig)
{
try
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SystemConfigSetting));
using (FileStream fs = new FileStream(CONFIGFILEPATH), FileMode.Open))
{
xmlSerializer.Serialize(fs, systemConfig);
fs.Close();
}
return true;
}
catch (Exception ex)
{
return false;
}
}
系统配置设置:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace HZSpreadSheet.Model
{
[Serializable]
[XmlRoot]
public class SystemConfigSetting
{
private bool isRuntime = false;
private List<ReportScheduler> reportSchedulers = new List<ReportScheduler>();
[XmlAttribute]
public bool IsRuntime { get => isRuntime; set => isRuntime = value; }
[XmlArray]
[XmlArrayItem]
public List<ReportScheduler> ReportSchedulers { get => reportSchedulers; set => reportSchedulers = value; }
}
}
ReportScheduler:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace HZSpreadSheet.Model
{
public enum ReportSaveFrequency
{
Daily = 0,
Weekly = 1,
Monthly = 2,
Manually =3
}
public enum DayofWeek
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6
}
[XmlRoot]
public class ReportScheduler
{
private string abbr_reportName;
private string fullreportName;
private bool isEnableAutosaveReport = false;
private int hour = 0;
private int minute = 0;
private int second =0;
private DateTime lastUpdate;
private DayofWeek dayofWeek;
private ReportSaveFrequency reportSaveFrequency;
[XmlAttribute]
public string ReportName { get => abbr_reportName; set => abbr_reportName = value; }
[XmlAttribute]
public string FullreportName { get => fullreportName; set => fullreportName = value; }
[XmlAttribute]
public bool IsEnableAutosaveReport { get => isEnableAutosaveReport; set => isEnableAutosaveReport = value; }
[XmlAttribute]
public int Hour { get => hour; set => hour = value; }
[XmlAttribute]
public int Minute { get => minute; set => minute = value; }
[XmlAttribute]
public int Second { get => second; set => second = value; }
[XmlAttribute]
public ReportSaveFrequency ReportSaveFrequency { get => reportSaveFrequency; set => reportSaveFrequency = value; }
[XmlAttribute]
public DayofWeek DayofWeek { get => dayofWeek; set => dayofWeek = value; }
[XmlAttribute]
public DateTime LastUpdate { get => lastUpdate; set => lastUpdate = value; }
}
}
如果您覆盖一个文件(或类似的流)并用较短的数据覆盖一个更长的文件,而不截断它,就会发生这种情况。如果您打开现有文件以使用写入 (FileMode.Open
) 进行随机访问,它会假设您要编辑内容,但 not 会假设您只需要新位.您看到的是来自 old 负载的额外字节,这些字节不会自动删除。有两种截断方式:
- 打开文件时使用
FileMode.Create
,将文件初始化为零长度 - 写完后在
Stream
上使用SetLength
,告诉它新的长度 - 例如stream.SetLength(stream.Position);