通过为实例调用自己的静态函数,我得到了一个具有某些属性的类的对象。如果存在XML文件,则该对象尝试加载它并将其值添加到实例本身。然后,如果XML文件中缺少选项,它将再次保存XML。
我创建了一个小型控制台应用程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using System.Xml;
namespace Test
{
public class Program
{
static void Main(string[] args)
{
TaskServerSettings s = TaskServerSettings.LoadNew();
}
}
public class TaskServerSettings : IEqualityComparer
{
#region SETTINGS PROPERTIES
public bool Enabled { get; set; }
public int CheckInterval { get; set; }
#endregion
#region CONSTRUCTORS AND METHODS
public TaskServerSettings()
{
this.init();
}
public TaskServerSettings(string settingsFile)
{
this.init();
if (settingsFile != null)
{
if (File.Exists(settingsFile))
{
this.Load(settingsFile);
}
this.Save(settingsFile);
}
}
private void init()
{
this.Enabled = true;
this.CheckInterval = 5000;
}
public void Absorb(TaskServerSettings newSettings)
{
this.Enabled = newSettings.Enabled;
this.CheckInterval = newSettings.CheckInterval;
}
public static TaskServerSettings LoadNew(string settingsFile = null)
{
if (settingsFile == null)
{
settingsFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.TrimEnd('\\')) + @"\TaskServerSettings.xml";
}
return new TaskServerSettings(settingsFile);
}
public bool Load(string settingsFile = null)
{
if (settingsFile == null)
{
settingsFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.TrimEnd('\\')) + @"\TaskServerSettings.xml";
}
if (!File.Exists(settingsFile))
{
throw new FileNotFoundException("Could not find \"" + settingsFile + "\" to load settings.");
}
bool result = false;
using (FileStream fs = new FileStream(settingsFile, FileMode.Open))
{
XmlSerializer xs = new XmlSerializer(this.GetType());
if (!xs.CanDeserialize(XmlReader.Create(fs)))
{
throw new XmlException("\"" + settingsFile + "\" does not have a valid TaskServerSettings XML structure.");
}
//try
//{ // +- InvalidOperationException - Error in XML document (0,0).
// v The root element is missing.
this.Absorb(xs.Deserialize(fs) as TaskServerSettings);
result = true;
//}
//catch { }
}
return result;
}
public bool Save(string settingsFile = null)
{
if (settingsFile == null)
{
settingsFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.TrimEnd('\\')) + @"\TaskServerSettings.xml";
}
bool result = false;
using (FileStream fs = new FileStream(settingsFile, FileMode.Create))
{
XmlSerializer xs = new XmlSerializer(this.GetType());
try
{
xs.Serialize(fs, this);
result = true;
}
catch { }
}
return result;
}
#endregion
public bool Equals(TaskServerSettings settingsToCompare)
{
if (this.Enabled != settingsToCompare.Enabled ||
this.CheckInterval != settingsToCompare.CheckInterval)
{
return false;
}
return true;
}
bool IEqualityComparer.Equals(object x, object y)
{
return x.Equals(y);
}
int IEqualityComparer.GetHashCode(object obj)
{
throw new NotSupportedException();
}
}
}
在第一次运行中使用默认属性值编写对象非常有用。 XML文件如下所示:
<?xml version="1.0"?>
<TaskServerSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Enabled>true</Enabled>
<CheckInterval>5000</CheckInterval>
</TaskServerSettings>
但是,在第二次运行时反序列化同一文件会在尝试加载文件时导致错误
xs.Deserialize(fs) as TaskServerSettings
。
InvalidOperationException - Error in XML document (0,0).
The root element is missing.
我已经尝试避免静态方法并尝试new
以及我已经尝试删除IEqualityComparer
父+前三种方法。没有成功。
我想知道,这个错误的原因是什么?
答案 0 :(得分:3)
执行此声明时:
if (!xs.CanDeserialize(XmlReader.Create(fs)))
它开始阅读流。因此,当您稍后调用Deserialize
时,流不在开头,因此反序列化失败。您需要通过设置fs.Position = 0