using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Xml.Serialization;
|
|
using System.IO;
|
|
using System.Xml;
|
|
|
|
namespace Utils.Files
|
|
{
|
|
/// <summary>
|
|
/// 通过XML文件保存配置信息;读取通过XML文件保存配置信息
|
|
/// <para>只处理两级信息:根、根的下一级。如果有更多级,则读取的信息将会出错</para>
|
|
/// </summary>
|
|
/// <typeparam name="T">配置数据保存在类型为T的对象中</typeparam>
|
|
public class XmlConfig<T>
|
|
{
|
|
/// <summary>
|
|
/// 通过XML文件设置配置信息
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">文件名(程序所在目录)或路径+文件名</param>
|
|
/// <param name="setting">配置信息</param>
|
|
public static void SetConfig(string fileName_pathAndFileName, T setting)
|
|
{
|
|
XmlSerializer ser = new XmlSerializer(typeof(T));
|
|
TextWriter wr = new StreamWriter(fileName_pathAndFileName);
|
|
ser.Serialize(wr, setting);
|
|
wr.Close();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有配置信息。只包含两级信息,即:根、根的下一级
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">文件名(程序所在目录)或路径+文件名</param>
|
|
public static Dictionary<string, string> GetAllConfigs(string fileName_pathAndFileName)
|
|
{
|
|
XmlDocument xmlDoc = Load(fileName_pathAndFileName);
|
|
|
|
return GetAllConfigs(xmlDoc);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有配置信息。只包含两级信息,即:根、根的下一级
|
|
/// </summary>
|
|
/// <param name="xmlDoc">读取出的xml文档信息</param>
|
|
public static Dictionary<string, string> GetAllConfigs(XmlDocument xmlDoc)
|
|
{
|
|
XmlNode rootNode = xmlDoc.ChildNodes[1];//根节点
|
|
|
|
return findChild(rootNode, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 向配置文件中增加配置信息。如果已存在,则为修改配置信息
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">配置文件的文件名</param>
|
|
/// <param name="name">配置信息的名字</param>
|
|
/// <param name="value">配置信息的内容</param>
|
|
public static void AddConfig(string fileName_pathAndFileName, string name, string value)
|
|
{
|
|
XmlDocument xmlDoc = Load(fileName_pathAndFileName);
|
|
|
|
var configs = GetAllConfigs(xmlDoc);
|
|
AddOrChange(xmlDoc, configs, name, value);
|
|
xmlDoc.Save(fileName_pathAndFileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 向配置文件中增加配置信息。如果已存在,则为修改配置信息
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">配置文件的文件名</param>
|
|
/// <param name="configs">配置信息。key为名字,value为内容</param>
|
|
public static void AddConfig(string fileName_pathAndFileName, Dictionary<string, string> configs)
|
|
{
|
|
XmlDocument xmlDoc = Load(fileName_pathAndFileName);
|
|
var oldConfigs = GetAllConfigs(xmlDoc);
|
|
foreach (var config in configs) {
|
|
AddOrChange(xmlDoc, oldConfigs, config.Key, config.Value);
|
|
}
|
|
xmlDoc.Save(fileName_pathAndFileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取指定的配置。没有则返回null
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">文件名(程序所在目录)或路径+文件名</param>
|
|
/// <param name="name">要获取的配置的名称</param>
|
|
public static string GetConfig(string fileName_pathAndFileName, string name)
|
|
{
|
|
if (GetAllConfigs(fileName_pathAndFileName).Keys.Contains(name))
|
|
return GetAllConfigs(fileName_pathAndFileName)[name];
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取指定的配置,结果为字符串数组。没有则返回空数组,即:{}
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">文件名(程序所在目录)或路径+文件名</param>
|
|
/// <param name="name">要获取的配置的名称</param>
|
|
/// <param name="values">配置内容</param>
|
|
public static void GetConfig(string fileName_pathAndFileName, string name, out string[] values)
|
|
{
|
|
var valuesArr = GetConfig(fileName_pathAndFileName, name);
|
|
if (!string.IsNullOrEmpty(valuesArr))
|
|
values = valuesArr.Split(',');
|
|
else
|
|
values = new string[] { };
|
|
}
|
|
|
|
private static Dictionary<string, string> findChild(XmlNode rootNode, bool includeEmpty)
|
|
{
|
|
Dictionary<string, string> reslut = new Dictionary<string, string>();
|
|
|
|
XmlNodeList list = rootNode.ChildNodes;
|
|
if (list == null || list.Count == 0)
|
|
return reslut;
|
|
foreach (XmlNode node in list) {
|
|
if (node.HasChildNodes && node.ChildNodes.Count > 0) {
|
|
if (node.ChildNodes.Count == 1 && node.FirstChild.NodeType == XmlNodeType.Text) {
|
|
reslut.Add(node.Name, node.InnerText);
|
|
} else {
|
|
throw new ApplicationException("配置不正确");
|
|
}
|
|
} else {
|
|
if (includeEmpty)
|
|
reslut.Add(node.Name, node.InnerText);
|
|
}
|
|
}
|
|
|
|
return reslut;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 从配置文件中读取信息。成功则返回true,并返回代表该配置文件的对象;文件不存在则返回false。
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">配置文件的名称或路径名称</param>
|
|
/// <param name="xmlDoc">代表读取出来的文件的对象</param>
|
|
/// <returns>成功则返回true,并返回代表该配置文件的对象;文件不存在则返回false。</returns>
|
|
protected static bool Load(string fileName_pathAndFileName, out XmlDocument xmlDoc)
|
|
{
|
|
xmlDoc = new XmlDocument();
|
|
try {
|
|
xmlDoc.Load(fileName_pathAndFileName);
|
|
} catch (FileNotFoundException) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取代表配置文件的对象。如果不存在,则创建空配置文件,并返回代表该配置文件的对象。
|
|
/// </summary>
|
|
/// <param name="fileName_pathAndFileName">文件名</param>
|
|
protected static XmlDocument Load(string fileName_pathAndFileName)
|
|
{
|
|
XmlDocument xmlDoc;
|
|
if (!Load(fileName_pathAndFileName, out xmlDoc)) {//当文件不存在时
|
|
Configs setting = new Configs();
|
|
XmlConfig<Configs>.SetConfig(fileName_pathAndFileName, setting);
|
|
Load(fileName_pathAndFileName, out xmlDoc);
|
|
}
|
|
return xmlDoc;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加或修改配置信息。添加、修改取决于name是否存在
|
|
/// <para>要使修改生效,还需要在调用该方法后,进行保存操作</para>
|
|
/// </summary>
|
|
/// <param name="xmlDoc">代表配置文件的对象</param>
|
|
/// <param name="configs">从配置文件中读取出来的配置信息(用于方法内的查询)</param>
|
|
/// <param name="name">配置名字</param>
|
|
/// <param name="value">配置对应的值</param>
|
|
private static void AddOrChange(XmlDocument xmlDoc, Dictionary<string, string> configs, string name, string value)
|
|
{
|
|
if (configs.Keys.Contains(name))
|
|
foreach (XmlNode node in xmlDoc.ChildNodes[1].ChildNodes) {
|
|
if (node.Name == name) {
|
|
node.InnerText = value;
|
|
return;
|
|
}
|
|
}
|
|
|
|
XmlNode rootNode = xmlDoc.ChildNodes[1];//根节点
|
|
XmlElement element = xmlDoc.CreateElement(name);
|
|
element.InnerText = value;
|
|
rootNode.AppendChild(element);
|
|
}
|
|
|
|
}
|
|
|
|
#region
|
|
public struct Configs//空结构,用于创建配置信息为空的配置文件(并不是什么信息都没有)
|
|
{
|
|
}
|
|
|
|
public class XmlConfig : XmlConfig<Configs>
|
|
{
|
|
public static Dictionary<string, TrinaryValue> GetAllSystemConfigs(string fileName_pathAndFileName)
|
|
{
|
|
XmlDocument xmlDoc;
|
|
return GetAllSystemConfigs(fileName_pathAndFileName, out xmlDoc);
|
|
}
|
|
|
|
private static Dictionary<string, TrinaryValue> GetAllSystemConfigs(string fileName_pathAndFileName, out XmlDocument xmlDoc)
|
|
{
|
|
Dictionary<string, TrinaryValue> result = new Dictionary<string, TrinaryValue>();
|
|
//XmlDocument xmlDoc;
|
|
if (Load(fileName_pathAndFileName, out xmlDoc)) {
|
|
XmlNodeList list = xmlDoc.ChildNodes[1].ChildNodes;
|
|
if (list == null || list.Count == 0)
|
|
return new Dictionary<string, TrinaryValue>();
|
|
foreach (XmlNode node in list) {
|
|
if (node.Attributes.Count > 0) {
|
|
TrinaryValue value = new TrinaryValue();
|
|
foreach (XmlAttribute attr in node.Attributes) {
|
|
switch (attr.Name) {
|
|
case "Name":
|
|
value.Key = attr.Value;
|
|
break;
|
|
case "DisplayName":
|
|
value.DisplayName = attr.Value;
|
|
break;
|
|
case "WebRoot":
|
|
value.Value = attr.Value;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if (value.Key.Length > 0)
|
|
result.Add(value.Key, value);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static void AddConfig(string fileName_pathAndFileName, TrinaryValue attributeValue)
|
|
{
|
|
XmlDocument xmlDoc;
|
|
var configs = GetAllSystemConfigs(fileName_pathAndFileName, out xmlDoc);
|
|
if (!configs.Keys.Contains(attributeValue.Key))
|
|
throw new ApplicationException("错误!\n要修改的项不存在!\n这个错误不应出现");
|
|
bool hasChanged = false;
|
|
foreach (XmlNode node in xmlDoc.ChildNodes[1].ChildNodes) {
|
|
if (hasChanged)
|
|
break;
|
|
foreach (XmlAttribute attr in node.Attributes) {
|
|
if (attr.Name == "Name" && attr.Value == attributeValue.Key) {
|
|
ChangeAttribute(node, attributeValue);
|
|
hasChanged = true;
|
|
}
|
|
}
|
|
}
|
|
xmlDoc.Save(fileName_pathAndFileName);
|
|
}
|
|
|
|
private static void ChangeAttribute(XmlNode node, TrinaryValue attributeValue)
|
|
{
|
|
foreach (XmlAttribute attr in node.Attributes) {
|
|
switch (attr.Name) {
|
|
case "DisplayName":
|
|
attr.Value = attributeValue.DisplayName;
|
|
break;
|
|
case "WebRoot":
|
|
attr.Value = attributeValue.Value;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct TrinaryValue
|
|
{
|
|
public string Key { get; set; }
|
|
public string DisplayName { get; set; }
|
|
public string Value { get; set; }
|
|
}
|
|
|
|
#endregion
|
|
}
|