前言
在项目中,我们经常用到各种配置文件,比如xml文件、binary文件等等,这里主要根据实践经验介绍下xml文件的序列化和反序列化(毕竟最常用)。
实践背景:我要做一个用户管理功能,用户账号信息存储在xml/binary文件中,需要对其进行读写,而且为了不让用户修改,必须对其加密,当时想的有3种做法:
(1)实现读写xml配置文件,并将关键信息加密;
(2)实现读写binary配置文件,并将关键信息加密;
(3)直接对配置文件进行加密解密和读写,不管它所使用的文件格式是xml、binary或其它。
这三种做法我都实现了,不过经过最后manager的确认觉得采用第(3)种方法最好。
方法一:
(推荐: 本方法参考其思路)
(1)在我们将对象序列化为XML之前,对象的类代码必须包含各种自定义元数据属性(例如,[XmlAttributeAttribute(DataType = " date "])告诉编译器类及其字段和/或属性可以被序列化。
using System;using System.Xml.Serialization;using System.Collections.ObjectModel;namespace XXX.GlobalTypes{ ////// Save user account information /// [Serializable] [XmlRoot("UserManagement")] public class UserAccountInfo { private readonly Collection_users = new Collection (); [XmlElement("UserAccountInfo")] public Collection Users { get { return this._users; } } } [Serializable] public class UserInfo { [XmlElement("UserName")] public string UserName { get; set; } [XmlElement("UserPwd")] public string UserPwd { get; set; } [XmlElement("UserRole")] public ACCESS_LEVEL UserRole { get; set; } [XmlElement("Description")] public string Description { get; set; } }}
(2)封装XML序列化的类(其中作为样例,我加入了加密解密的参数tDESkey,在将数据对象保存到xml文件后进行加密,从xml文件中读取数据前先进行解密):
1 using System; 2 using System.Xml; 3 using System.Security.Cryptography; 4 using System.Security.Cryptography.Xml; 5 using System.Xml.Serialization; // For serialization of an object to an XML Document file. 6 using System.Runtime.Serialization.Formatters.Binary; // For serialization of an object to an XML Binary file. 7 using System.IO; // For reading/writing data to an XML file. 8 using System.IO.IsolatedStorage; // For accessing user isolated data. 9 10 namespace XXX.Utilities.Common 11 { 12 ///13 /// Serialization format types. 14 /// 15 public enum SerializedFormat 16 { 17 ///18 /// Binary serialization format. 19 /// 20 Binary, 21 22 ///23 /// Document serialization format. 24 /// 25 Document 26 } 27 28 29 ///30 /// Facade to XML serialization and deserialization of strongly typed objects to/from an XML file. 31 /// 32 /// References: XML Serialization at http://samples.gotdotnet.com/: 33 /// http://samples.gotdotnet.com/QuickStart/howto/default.aspx?url=/quickstart/howto/doc/xmlserialization/rwobjfromxml.aspx 34 /// 35 public static class ObjectXMLSerializerwhere T : class // Specify that T must be a class. 36 { 37 #region Load methods 38 39 /// 40 /// Loads an object from an XML file in Document format. 41 /// 42 ///43 /// 47 /// Path of the file to load the object from. 48 ///44 /// serializableObject = ObjectXMLSerializer<SerializableObject>.Load(@"C:\XMLObjects.xml"); 45 ///
46 ///Object loaded from an XML file in Document format. 49 public static T Load(string path, TripleDESCryptoServiceProvider tDESkey) 50 { 51 T serializableObject = LoadFromDocumentFormat(null, path, null, tDESkey); 52 return serializableObject; 53 } 54 55 ///56 /// Loads an object from an XML file using a specified serialized format. 57 /// 58 ///59 /// 63 /// Path of the file to load the object from. 64 /// XML serialized format used to load the object. 65 ///60 /// serializableObject = ObjectXMLSerializer<SerializableObject>.Load(@"C:\XMLObjects.xml", SerializedFormat.Binary); 61 ///
62 ///Object loaded from an XML file using the specified serialized format. 66 public static T Load(string path, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey) 67 { 68 T serializableObject = null; 69 70 switch (serializedFormat) 71 { 72 case SerializedFormat.Binary: 73 serializableObject = LoadFromBinaryFormat(path, null); 74 break; 75 76 case SerializedFormat.Document: 77 default: 78 serializableObject = LoadFromDocumentFormat(null, path, null, tDESkey); 79 break; 80 } 81 82 return serializableObject; 83 } 84 85 ///86 /// Loads an object from an XML file in Document format, supplying extra data types to enable deserialization of custom types within the object. 87 /// 88 ///89 /// 93 /// Path of the file to load the object from. 94 /// Extra data types to enable deserialization of custom types within the object. 95 ///90 /// serializableObject = ObjectXMLSerializer<SerializableObject>.Load(@"C:\XMLObjects.xml", new Type[] { typeof(MyCustomType) }); 91 ///
92 ///Object loaded from an XML file in Document format. 96 public static T Load(string path, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey) 97 { 98 T serializableObject = LoadFromDocumentFormat(extraTypes, path, null, tDESkey); 99 return serializableObject;100 }101 102 ///103 /// Loads an object from an XML file in Document format, located in a specified isolated storage area.104 /// 105 ///106 /// 110 /// Name of the file in the isolated storage area to load the object from.111 /// Isolated storage area directory containing the XML file to load the object from.112 ///107 /// serializableObject = ObjectXMLSerializer<SerializableObject>.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly());108 ///
109 ///Object loaded from an XML file in Document format located in a specified isolated storage area. 113 public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, TripleDESCryptoServiceProvider tDESkey)114 {115 T serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);116 return serializableObject;117 }118 119 ///120 /// Loads an object from an XML file located in a specified isolated storage area, using a specified serialized format.121 /// 122 ///123 /// 127 /// Name of the file in the isolated storage area to load the object from.128 /// Isolated storage area directory containing the XML file to load the object from.129 /// XML serialized format used to load the object. 130 ///124 /// serializableObject = ObjectXMLSerializer<SerializableObject>.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), SerializedFormat.Binary);125 ///
126 ///Object loaded from an XML file located in a specified isolated storage area, using a specified serialized format. 131 public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)132 {133 T serializableObject = null;134 135 switch (serializedFormat)136 {137 case SerializedFormat.Binary:138 serializableObject = LoadFromBinaryFormat(fileName, isolatedStorageDirectory);139 break;140 141 case SerializedFormat.Document:142 default:143 serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);144 break;145 }146 147 return serializableObject;148 }149 150 ///151 /// Loads an object from an XML file in Document format, located in a specified isolated storage area, and supplying extra data types to enable deserialization of custom types within the object.152 /// 153 ///154 /// 158 /// Name of the file in the isolated storage area to load the object from.159 /// Isolated storage area directory containing the XML file to load the object from.160 /// Extra data types to enable deserialization of custom types within the object.161 ///155 /// serializableObject = ObjectXMLSerializer<SerializableObject>.Load("XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), new Type[] { typeof(MyCustomType) });156 ///
157 ///Object loaded from an XML file located in a specified isolated storage area, using a specified serialized format. 162 public static T Load(string fileName, IsolatedStorageFile isolatedStorageDirectory, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)163 {164 T serializableObject = LoadFromDocumentFormat(null, fileName, isolatedStorageDirectory, tDESkey);165 return serializableObject;166 }167 168 #endregion169 170 #region Save methods171 172 ///173 /// Saves an object to an XML file in Document format.174 /// 175 ///176 /// 182 /// Serializable object to be saved to file.183 /// Path of the file to save the object to.184 public static void Save(T serializableObject, string path, TripleDESCryptoServiceProvider tDESkey)185 {186 SaveToDocumentFormat(serializableObject, null, path, null, tDESkey);187 }188 189 ///177 /// SerializableObject serializableObject = new SerializableObject();178 /// 179 /// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, @"C:\XMLObjects.xml");180 ///
181 ///190 /// Saves an object to an XML file using a specified serialized format.191 /// 192 ///193 /// 199 /// Serializable object to be saved to file.200 /// Path of the file to save the object to.201 /// XML serialized format used to save the object.202 public static void Save(T serializableObject, string path, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)203 {204 switch (serializedFormat)205 {206 case SerializedFormat.Binary:207 SaveToBinaryFormat(serializableObject, path, null);208 break;209 210 case SerializedFormat.Document:211 default:212 SaveToDocumentFormat(serializableObject, null, path, null, tDESkey);213 break;214 }215 }216 217 ///194 /// SerializableObject serializableObject = new SerializableObject();195 /// 196 /// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, @"C:\XMLObjects.xml", SerializedFormat.Binary);197 ///
198 ///218 /// Saves an object to an XML file in Document format, supplying extra data types to enable serialization of custom types within the object.219 /// 220 ///221 /// 227 /// Serializable object to be saved to file.228 /// Path of the file to save the object to.229 /// Extra data types to enable serialization of custom types within the object.230 public static void Save(T serializableObject, string path, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)231 {232 SaveToDocumentFormat(serializableObject, extraTypes, path, null, tDESkey);233 }234 235 ///222 /// SerializableObject serializableObject = new SerializableObject();223 /// 224 /// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, @"C:\XMLObjects.xml", new Type[] { typeof(MyCustomType) });225 ///
226 ///236 /// Saves an object to an XML file in Document format, located in a specified isolated storage area.237 /// 238 ///239 /// 245 /// Serializable object to be saved to file.246 /// Name of the file in the isolated storage area to save the object to.247 /// Isolated storage area directory containing the XML file to save the object to.248 public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, TripleDESCryptoServiceProvider tDESkey)249 {250 SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);251 }252 253 ///240 /// SerializableObject serializableObject = new SerializableObject();241 /// 242 /// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly());243 ///
244 ///254 /// Saves an object to an XML file located in a specified isolated storage area, using a specified serialized format.255 /// 256 ///257 /// 263 /// Serializable object to be saved to file.264 /// Name of the file in the isolated storage area to save the object to.265 /// Isolated storage area directory containing the XML file to save the object to.266 /// XML serialized format used to save the object. 267 public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, SerializedFormat serializedFormat, TripleDESCryptoServiceProvider tDESkey)268 {269 switch (serializedFormat)270 {271 case SerializedFormat.Binary:272 SaveToBinaryFormat(serializableObject, fileName, isolatedStorageDirectory);273 break;274 275 case SerializedFormat.Document:276 default:277 SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);278 break;279 }280 }281 282 ///258 /// SerializableObject serializableObject = new SerializableObject();259 /// 260 /// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), SerializedFormat.Binary);261 ///
262 ///283 /// Saves an object to an XML file in Document format, located in a specified isolated storage area, and supplying extra data types to enable serialization of custom types within the object.284 /// 285 ///286 /// 292 /// Serializable object to be saved to file.293 /// Name of the file in the isolated storage area to save the object to.294 /// Isolated storage area directory containing the XML file to save the object to.295 /// Extra data types to enable serialization of custom types within the object.296 public static void Save(T serializableObject, string fileName, IsolatedStorageFile isolatedStorageDirectory, System.Type[] extraTypes, TripleDESCryptoServiceProvider tDESkey)297 {298 SaveToDocumentFormat(serializableObject, null, fileName, isolatedStorageDirectory, tDESkey);299 }300 301 #endregion302 303 #region Private304 305 private static FileStream CreateFileStream(IsolatedStorageFile isolatedStorageFolder, string path)306 {307 FileStream fileStream = null;308 309 if (isolatedStorageFolder == null)310 fileStream = new FileStream(path, FileMode.OpenOrCreate);311 else312 fileStream = new IsolatedStorageFileStream(path, FileMode.OpenOrCreate, isolatedStorageFolder);313 314 return fileStream;315 }316 317 private static T LoadFromBinaryFormat(string path, IsolatedStorageFile isolatedStorageFolder)318 {319 T serializableObject = null;320 321 using (FileStream fileStream = CreateFileStream(isolatedStorageFolder, path))322 {323 BinaryFormatter binaryFormatter = new BinaryFormatter();324 serializableObject = binaryFormatter.Deserialize(fileStream) as T;325 }326 327 return serializableObject;328 }329 330 private static T LoadFromDocumentFormat(System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder, TripleDESCryptoServiceProvider tDESkey)331 {332 XmlDocument xmlDoc = new XmlDocument();333 try334 {335 xmlDoc.PreserveWhitespace = true;336 337 xmlDoc.Load(path);338 }339 catch (Exception e)340 {341 Console.WriteLine(e.Message);342 }343 344 // Decrypt the "UserManagement" element.345 EncryptXml.Decrypt(xmlDoc, tDESkey);346 xmlDoc.Save(path);347 348 T serializableObject = null;349 350 using (TextReader textReader = CreateTextReader(isolatedStorageFolder, path))351 {352 XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);353 serializableObject = xmlSerializer.Deserialize(textReader) as T;354 }355 356 EncryptXml.Encrypt(xmlDoc, "UserManagement", tDESkey);357 xmlDoc.Save(path);358 359 return serializableObject;360 }361 362 private static TextReader CreateTextReader(IsolatedStorageFile isolatedStorageFolder, string path)363 {364 TextReader textReader = null;365 366 if (isolatedStorageFolder == null)367 textReader = new StreamReader(path);368 else369 textReader = new StreamReader(new IsolatedStorageFileStream(path, FileMode.Open, isolatedStorageFolder));370 371 return textReader;372 }373 374 private static TextWriter CreateTextWriter(IsolatedStorageFile isolatedStorageFolder, string path)375 {376 TextWriter textWriter = null;377 378 if (isolatedStorageFolder == null)379 textWriter = new StreamWriter(path);380 else381 textWriter = new StreamWriter(new IsolatedStorageFileStream(path, FileMode.OpenOrCreate, isolatedStorageFolder));382 383 return textWriter;384 }385 386 private static XmlSerializer CreateXmlSerializer(System.Type[] extraTypes)387 {388 Type ObjectType = typeof(T);389 390 XmlSerializer xmlSerializer = null;391 392 if (extraTypes != null)393 xmlSerializer = new XmlSerializer(ObjectType, extraTypes);394 else395 xmlSerializer = new XmlSerializer(ObjectType);396 397 return xmlSerializer;398 }399 400 private static void SaveToDocumentFormat(T serializableObject, System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder, TripleDESCryptoServiceProvider tDESkey)401 {402 using (TextWriter textWriter = CreateTextWriter(isolatedStorageFolder, path))403 {404 XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);405 xmlSerializer.Serialize(textWriter, serializableObject);406 407 textWriter.Close();408 409 XmlDocument xmlDoc = new XmlDocument();410 try411 {412 xmlDoc.PreserveWhitespace = true;413 414 xmlDoc.Load(path);415 }416 catch (Exception e)417 {418 Console.WriteLine(e.Message);419 }420 421 EncryptXml.Encrypt(xmlDoc, "UserManagement", tDESkey);422 423 xmlDoc.Save(path);424 }425 }426 427 private static void SaveToBinaryFormat(T serializableObject, string path, IsolatedStorageFile isolatedStorageFolder)428 {429 using (FileStream fileStream = CreateFileStream(isolatedStorageFolder, path))430 {431 BinaryFormatter binaryFormatter = new BinaryFormatter();432 binaryFormatter.Serialize(fileStream, serializableObject);433 }434 }435 436 437 #endregion438 }439 }287 /// SerializableObject serializableObject = new SerializableObject();288 /// 289 /// ObjectXMLSerializer<SerializableObject>.Save(serializableObject, "XMLObjects.xml", IsolatedStorageFile.GetUserStoreForAssembly(), new Type[] { typeof(MyCustomType) });290 ///
291 ///
(3)Saving an object to an XML file/Loading an object from an XML file
// Load the userManagement object from the XML file using our UserAccountInfo class...UserAccountInfo userManagement =ObjectXMLSerializer.Load(path, tDESkey);// Load the userManagement object from the XML file using our userManagement class...ObjectXMLSerializer .Save(usermanagement, XML_FILE_NAME, tDESkey);
方法二:
其实,要想仅仅实现xml的序列化和反序列化还是很简单的,作为常用的类,可以很简单地将其实现为公共类:
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Xml;using System.Xml.Serialization;namespace XXX.Common{ public static class XmlHelper { public static object DeserializeObject(string filePath) { try { var xs = new XmlSerializer(typeof(T)); using (var fs = new FileStream(filePath, FileMode.Open)) { var reader = XmlReader.Create(fs); return xs.Deserialize(reader); } } catch (Exception exp) { throw new XmlException($"Failed in XML Deserialization {filePath}", exp); } } public static void SerializeObject (string filePath, T o) { try { var x = new XmlSerializer(typeof(T)); using (var fs = new FileStream(filePath, FileMode.Create)) { var writer = XmlWriter.Create(fs); x.Serialize(writer, o); } } catch (Exception exp) { throw new XmlException($"Failed in XML Serialization {filePath}", exp); } } }}
另可参考文章:
1.
2.