最近碰到一个问题,需要将程序中的一些基本参数写到xml文件中,虽然网上有好多现成的代码,但是觉得对xml不熟悉,果断就研究了一下。先说一下大体思路吧,我设计了一个用来读取和回填的类,然后定义了一个接口,和一个Attribute,之后就是继承该接口的若干个子类,列表如下:
1.用来读取xml和回填实体对象的类:ProgramSettings;
2.需要实现的接口:SettingsEntity;
3.用来约束类中那些属性不需要写入文件的Attribute:DontFill;
4.一个实现了接口的子类:SettingsEntity.
以下是代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.IO; 6 using System.Xml; 7 using System.Configuration; 8 using System.Reflection; 9 using WinControl; 10 using LogSystem; 11 12 namespace WirelessQAR 13 { 14 /* 15 *wanglei 2016/2/25 创建 用来保存程序设置到根目录下面的xml文件,在程序加载时进行读取 16 * 使用单体模式-饱汉模式 17 */ 18 public class ProgramSettings 19 { 20 private static ProgramSettings _programSettings = new ProgramSettings(); 21 22 private string _path = Environment.CurrentDirectory + "\\" + ConfigurationSettings.AppSettings["BaseSetting"]; 23 24 private ProgramSettings() 25 { 26 27 } 28 29 //确保能够得到符合标准的XMLDocument 30 private XmlDocument ReadXmlData(string path) 31 { 32 XmlDocument xmlDoc = new XmlDocument(); 33 try 34 { 35 if (!File.Exists(_path)) 36 { 37 FileStream fileStream = File.Create(_path); 38 StreamWriter streamWriter = new StreamWriter(fileStream); 39 streamWriter.Write("<root></root>"); 40 streamWriter.Flush(); 41 streamWriter.Close(); 42 xmlDoc.Load(_path); 43 } 44 else 45 { 46 xmlDoc.Load(path); 47 } 48 } 49 catch (Exception ex) 50 { 51 //记录日志或者提示出信息 53 } 54 55 if (xmlDoc.DocumentElement == null) 56 { 57 if (File.Exists(_path)) 58 { 59 StreamReader streamReader = File.OpenText(_path); 60 string copy = streamReader.ReadToEnd(); 61 if (!string.IsNullOrEmpty(copy.Trim())) 62 { 63 FileStream copyFile = File.Open(Environment.CurrentDirectory + "\\" + "baseSettingClone.txt", FileMode.OpenOrCreate); 64 StreamWriter streamWriter = new StreamWriter(copyFile); 65 streamWriter.Write("\r\n" + DateTime.Now.ToString() + "\r\n" + copy); 66 streamWriter.Flush(); 67 streamWriter.Close(); 68 } 69 streamReader.Close(); 70 File.Delete(_path); 71 } 72 73 FileStream fileStream = File.Create(_path); 74 StreamWriter streamWriterNew = new StreamWriter(fileStream); 75 streamWriterNew.Write("<root></root>"); 76 streamWriterNew.Flush(); 77 streamWriterNew.Close(); 78 xmlDoc.Load(_path); 79 80 } 81 return xmlDoc; 82 } 83 84 public static ProgramSettings GetInstance() 85 { 86 if (_programSettings == null) 87 { 88 _programSettings = new ProgramSettings(); 89 } 90 return _programSettings; 91 } 92 93 public SettingsEntity ReadSettings(SettingsEntity entity) 94 { 95 if (entity != null) 96 { 97 Type entityType = entity.GetType(); 98 System.Reflection.PropertyInfo[] properties = entityType.GetProperties(); 99 XmlDocument xmlDoc = ReadXmlData(_path); 100 if (xmlDoc.DocumentElement != null) 101 { 102 XmlNode firstChild = xmlDoc.DocumentElement.SelectSingleNode(entity.SettingsName); 103 if (firstChild != null) 104 { 105 foreach (XmlNode node in firstChild.ChildNodes) 106 { 107 System.Reflection.PropertyInfo property = entityType.GetProperty(node.Name); 108 if (property != null && property.GetCustomAttributes(typeof(DontFill), false).Length < 1) 109 { 110 SetPropertyValue(entity, property, node.InnerText); 111 } 112 } 113 } 114 } 115 } 116 return entity; 117 } 118 119 private void SetPropertyValue(object entity, PropertyInfo property, object value) 120 { 121 switch (property.PropertyType.ToString()) 122 { 123 case "System.Int32": 124 property.SetValue(entity, Convert.ToInt32(value), null); 125 break; 126 case "System.Boolean": 127 property.SetValue(entity, Convert.ToBoolean(value), null); 128 break; 129 case "System.DateTime": 130 property.SetValue(entity, Convert.ToDateTime(value), null); 131 break; 132 case "System.Decimal": 133 property.SetValue(entity, Convert.ToDecimal(value), null); 134 break; 135 case "System.Double": 136 property.SetValue(entity, Convert.ToDouble(value), null); 137 break; 138 case "System.Int64": 139 property.SetValue(entity, Convert.ToInt64(value), null); 140 break; 141 default: 142 property.SetValue(entity, value, null); 143 break; 144 } 145 } 146 147 public void SaveSettings(SettingsEntity entity) 148 { 149 if (entity != null) 150 { 151 Type entityType = entity.GetType(); 152 PropertyInfo[] properties = entityType.GetProperties(); 153 XmlDocument xmlDoc = ReadXmlData(_path); 154 155 XmlNode nodeEntity = xmlDoc.DocumentElement.SelectSingleNode(entity.SettingsName); 156 157 if (nodeEntity != null) 158 { 159 foreach (System.Reflection.PropertyInfo property in properties) 160 { 161 if (property.GetCustomAttributes(typeof(DontFill), false).Length < 1) 162 { 163 foreach (XmlNode cnode in nodeEntity.ChildNodes) 164 { 165 if (property.Name.Equals(cnode.Name)) 166 { 167 cnode.InnerText = property.GetValue(entity, null).ToString(); 168 break; 169 } 170 } 171 } 172 } 173 } 174 else 175 { 176 XmlNode node = xmlDoc.CreateNode(XmlNodeType.Element, entity.SettingsName, null); 177 178 foreach (System.Reflection.PropertyInfo property in properties) 179 { 180 if (property.GetCustomAttributes(typeof(DontFill), false).Length < 1) 181 { 182 XmlNode element = xmlDoc.CreateNode(XmlNodeType.Element, property.Name, null); 183 element.InnerText = property.GetValue(entity, null).ToString(); 184 node.AppendChild(element); 185 } 186 } 187 xmlDoc.DocumentElement.AppendChild(node); 188 } 189 xmlDoc.Save(_path); 190 } 191 } 192 } 193 194 /// <summary> 195 /// 用来限定属性是否需要保存到配置文件中 196 /// </summary> 197 public class DontFill : Attribute 198 { 199 200 } 201 202 public interface SettingsEntity 203 { 204 string SettingsName{get;set;} 205 } 206 207 public class MonitorSettingsEntity : SettingsEntity 208 { 209 private string _settingsName = "MonitorSettings"; 210 211 [DontFill] 212 public string SettingsName 213 { 214 get { return _settingsName; } 215 set { this._settingsName = value; } 216 } 217 218 string _monitorFilePath = string.Empty; 219 public string MonitorFilePath 220 { 221 get { return _monitorFilePath; } 222 set { _monitorFilePath = value; } 223 } 224 int _maxThread = 5; 225 public int MaxThread 226 { 227 get { return _maxThread; } 228 set { _maxThread = value; } 229 } 230 231 long _monitorInterval = 1000000; 232 233 public long MonitorInterval 234 { 235 get { return _monitorInterval; } 236 set { _monitorInterval = value; } 237 } 238 239 long _infoBarMaxLines = 100; 240 241 public long InfoBarMaxLines 242 { 243 get { return _infoBarMaxLines; } 244 set { _infoBarMaxLines = value; } 245 } 246 } 247 248 249 }