我们来看看这个类的代码,上面有我的注释,获取有些地方说得不正确,那也没办法啦!
序列化
1 /**//// <summary>
2 /// 序列化类。
3 /// </summary>
4 public class Serializer
5 {
6 //防止被实例化。
7 private Serializer()
8 {
9
10 }
11 /**//// <summary>
12 /// 静态构造函数仅在设置CanBinarySerialize值中使用一次。
13 /// </summary>
14 static Serializer()
15 {
16 SecurityPermission sp = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
17 try
18 {
19 sp.Demand();
20 CanBinarySerialize = true;
21 }
22 catch (SecurityException)
23 {
24 CanBinarySerialize = false;
25 }
26 }
27 /**//// <summary>
28 /// 获取二进制序列化是否被使用。
29 /// </summary>
30 public static readonly bool CanBinarySerialize;
31 /**//// <summary>
32 /// 将对象转化成二进制的数组。
33 /// </summary>
34 /// <param name="objectToConvert">用于转化的对象。</param>
35 /// <returns>返回转化后的数组,如果CanBinarySerialize为false则返回null。</returns>
36 public static byte[] ConvertToBytes(object objectToConvert)
37 {
38 byte[] byteArray = null;
39
40 if (CanBinarySerialize)
41 {
42 BinaryFormatter binaryFormatter = new BinaryFormatter();
43 using (MemoryStream ms = new MemoryStream())
44 {
45
46 binaryFormatter.Serialize(ms, objectToConvert);
47 //设置是内存存储位置为0。
48 ms.Position = 0;
49 //读取数组。
50 byteArray = new Byte[ms.Length];
51 ms.Read(byteArray, 0, byteArray.Length);
52 ms.Close();
53 }
54 }
55 return byteArray;
56 }
57 /**//// <summary>
58 /// 将对象以二进制形式存储到硬盘中。
59 /// </summary>
60 /// <param name="objectToSave">用于保存的对象。</param>
61 /// <param name="path">文件路径。</param>
62 /// <returns>如果存储成功则返回true,否则返回false。</returns>
63 public static bool SaveAsBinary(object objectToSave, string path)
64 {
65 if (objectToSave != null && CanBinarySerialize)
66 {
67 byte[] ba = ConvertToBytes(objectToSave);
68 if (ba != null)
69 {
70 using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
71 {
72 using (BinaryWriter bw = new BinaryWriter(fs))
73 {
74 bw.Write(ba);
75 return true;
76 }
77 }
78 }
79 }
80 return false;
81 }
82 /**//// <summary>
83 ///将对象转化为XML格式文件,该对象必须用[Serialize]标记,否则将抛出错误。
84 /// </summary>
85 /// <param name="objectToConvert">用于序列化的标记。</param>
86 /// <returns>返回XML文本,如果对象为空则返回null。</returns>
87 public static string ConvertToString(object objectToConvert)
88 {
89 string xml = null;
90
91 if (objectToConvert != null)
92 {
93 //获取当前序列化对象。
94 Type t = objectToConvert.GetType();
95
96 XmlSerializer ser = new XmlSerializer(t);
97 //将序列化的结果保存到XML中。
98 using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
99 {
100 ser.Serialize(writer, objectToConvert);
101 xml = writer.ToString();
102 writer.Close();
103 }
104 }
105
106 return xml;
107 }
108 /**//// <summary>
109 /// 将对象序列化后以XML格式存储于文件中。
110 /// </summary>
111 /// <param name="objectToConvert">用于序列化的对象。</param>
112 /// <param name="path">用于存储的文件路径。</param>
113 public static void SaveAsXML(object objectToConvert, string path)
114 {
115 if (objectToConvert != null)
116 {
117 Type t = objectToConvert.GetType();
118
119 XmlSerializer ser = new XmlSerializer(t);
120
121 using (StreamWriter writer = new StreamWriter(path))
122 {
123 ser.Serialize(writer, objectToConvert);
124 writer.Close();
125 }
126 }
127
128 }
129 /**//// <summary>
130 /// 将一个二进制的数组转化为对象,必须通过类型转化自己想得到的相应对象。如果数组为空则返回空。
131 /// </summary>
132 /// <param name="byteArray">用于转化的二进制数组。</param>
133 /// <returns>返回转化后的对象实例,如果数组为空,则返回空对象。</returns>
134 public static object ConvertToObject(byte[] byteArray)
135 {
136 object convertedObject = null;
137 if (CanBinarySerialize && byteArray != null && byteArray.Length > 0)
138 {
139 BinaryFormatter binaryFormatter = new BinaryFormatter();
140 using (MemoryStream ms = new MemoryStream())
141 {
142 ms.Write(byteArray, 0, byteArray.Length);
143
144 ms.Position = 0;
145
146 if (byteArray.Length > 4)
147 convertedObject = binaryFormatter.Deserialize(ms);
148
149 ms.Close();
150 }
151 }
152 return convertedObject;
153 }
154 /**//// <summary>
155 /// 将文件的数据转化为对象。
156 /// </summary>
157 /// <param name="path">文件路径。</param>
158 /// <param name="objectType">希望得到的对象。</param>
159 /// <returns>返回反序列化的对象。</returns>
160 public static object ConvertFileToObject(string path, Type objectType)
161 {
162 object convertedObject = null;
163
164 if (path != null && path.Length > 0)
165 {
166 using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
167 {
168 XmlSerializer ser = new XmlSerializer(objectType);
169 convertedObject = ser.Deserialize(fs);
170 fs.Close();
171 }
172 }
173 return convertedObject;
174 }
175 /**//// <summary>
176 /// 将XML格式的字符串反序列化为实例对象。
177 /// </summary>
178 /// <param name="xml">Xml格式字符串。</param>
179 /// <param name="objectType">反序列化后所期望的对象。</param>
180 /// <returns>反序列化后所期望的对象,如果字符串为空,则返回空对象。</returns>
181 public static object ConvertToObject(string xml, Type objectType)
182 {
183 object convertedObject = null;
184
185 if (!WebHelper.IsNullOrEmpty(xml))
186 {
187 using (StringReader reader = new StringReader(xml))
188 {
189 XmlSerializer ser = new XmlSerializer(objectType);
190 convertedObject = ser.Deserialize(reader);
191 reader.Close();
192 }
193 }
194 return convertedObject;
195 }
196 /**//// <summary>
197 /// 将XML节点反序列化为实例对象。
198 /// </summary>
199 /// <param name="xml">用于反序列化的XML节点。</param>
200 /// <param name="objectType">反序列化后所期望的对象。</param>
201 /// <returns>反序列化后所期望的对象,如果字符串为空,则返回空对象。</returns>
202 public static object ConvertToObject(XmlNode node, Type objectType)
203 {
204 object convertedObject = null;
205
206 if (node != null)
207 {
208 using (StringReader reader = new StringReader(node.OuterXml))
209 {
210
211 XmlSerializer ser = new XmlSerializer(objectType);
212
213 convertedObject = ser.Deserialize(reader);
214
215 reader.Close();
216 }
217 }
218 return convertedObject;
219 }
220 /**//// <summary>
221 /// 加载一个二进制文件并将其转化为实例对象。
222 /// </summary>
223 /// <param name="path">文件路径。</param>
224 /// <returns>返回转化后的实例对象。</returns>
225 public static object LoadBinaryFile(string path)
226 {
227 if (!File.Exists(path))
228 return null;
229
230 using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
231 {
232 BinaryReader br = new BinaryReader(fs);
233 byte[] ba = new byte[fs.Length];
234 br.Read(ba, 0, (int)fs.Length);
235 return ConvertToObject(ba);
236 }
237 }
238 /**//// <summary>
239 /// 将字符串序列化<see cref="System.Collections.Specialized.NameValueCollection"/>类型,第一个为键,第二位与其相对应的值。
240 /// </summary>
241 /// <param name="keys">NameValueCollection中的keys键。</param>
242 /// <param name="values">NameValueCollection中的keys键对应的value。</param>
243 /// <returns>基于key-value格式的NameValeCollection集合对象。</returns>
244 /// <example>
245 /// string keys = "key1:S:0:3:key2:S:3:2:";
246 /// string values = "12345";
247 /// 则这个所得的NameValueCollection结果中包含两个键(key1和key2),他们所对应的值分别为(123和45)。
248 /// 其中:"key1:S:0:3"的key1表示键,S表示字符类型,0表示values起始的位置,3表示values结束的位置。
249 /// </example>
250 public static NameValueCollection ConvertToNameValueCollection(string keys, string values)
251 {
252 NameValueCollection nvc = new NameValueCollection();
253
254 if (keys != null && values != null && keys.Length > 0 && values.Length > 0)
255 {
256 char[] splitter = new char[1] { ':' };
257 string[] keyNames = keys.Split(splitter);
258
259 for (int i = 0; i < (keyNames.Length / 4); i++)
260 {
261 int start = int.Parse(keyNames[(i * 4) + 2], CultureInfo.InvariantCulture);
262 int len = int.Parse(keyNames[(i * 4) + 3], CultureInfo.InvariantCulture);
263 string key = keyNames[i * 4];
264
265 //Future version will support more complex types
266 if (((keyNames[(i * 4) + 1] == "S") && (start >= 0)) && (len > 0) && (values.Length >= (start + len)))
267 {
268 nvc[key] = values.Substring(start, len);
269 }
270 }
271 }
272
273 return nvc;
274 }
275 /**//// <summary>
276 /// 基于NameValueCollection对象序列化成keys和values的字符串。
277 /// </summary>
278 /// <param name="nvc">用于序列化的NameValueCollection对象。</param>
279 /// <param name="keys">ref格式的参数keys将转化为NameValueCollection中的key。</param>
280 /// <param name="values">ref格式的参数values将转化为NameValueCollection中的value。</param>
281 public static void ConvertFromNameValueCollection(NameValueCollection nvc, ref string keys, ref string values)
282 {
283 if (nvc == null || nvc.Count == 0)
284 return;
285
286 StringBuilder sbKey = new StringBuilder();
287 StringBuilder sbValue = new StringBuilder();
288
289 int index = 0;
290 foreach (string key in nvc.AllKeys)
291 {
292 if (key.IndexOf(':') != -1)
293 throw new ArgumentException("ExtendedAttributes Key can not contain the character \":\"");
294
295 string v = nvc[key];
296 if (!WebHelper.IsNullOrEmpty(v))
297 {
298 sbKey.AppendFormat("{0}:S:{1}:{2}:", key, index, v.Length);
299 sbValue.Append(v);
300 index += v.Length;
301 }
302 }
303 keys = sbKey.ToString();
304 values = sbValue.ToString();
305 }
306 }
1 /**//// <summary>
2 /// 序列化类。
3 /// </summary>
4 public class Serializer
5 {
6 //防止被实例化。
7 private Serializer()
8 {
9
10 }
11 /**//// <summary>
12 /// 静态构造函数仅在设置CanBinarySerialize值中使用一次。
13 /// </summary>
14 static Serializer()
15 {
16 SecurityPermission sp = new SecurityPermission(SecurityPermissionFlag.SerializationFormatter);
17 try
18 {
19 sp.Demand();
20 CanBinarySerialize = true;
21 }
22 catch (SecurityException)
23 {
24 CanBinarySerialize = false;
25 }
26 }
27 /**//// <summary>
28 /// 获取二进制序列化是否被使用。
29 /// </summary>
30 public static readonly bool CanBinarySerialize;
31 /**//// <summary>
32 /// 将对象转化成二进制的数组。
33 /// </summary>
34 /// <param name="objectToConvert">用于转化的对象。</param>
35 /// <returns>返回转化后的数组,如果CanBinarySerialize为false则返回null。</returns>
36 public static byte[] ConvertToBytes(object objectToConvert)
37 {
38 byte[] byteArray = null;
39
40 if (CanBinarySerialize)
41 {
42 BinaryFormatter binaryFormatter = new BinaryFormatter();
43 using (MemoryStream ms = new MemoryStream())
44 {
45
46 binaryFormatter.Serialize(ms, objectToConvert);
47 //设置是内存存储位置为0。
48 ms.Position = 0;
49 //读取数组。
50 byteArray = new Byte[ms.Length];
51 ms.Read(byteArray, 0, byteArray.Length);
52 ms.Close();
53 }
54 }
55 return byteArray;
56 }
57 /**//// <summary>
58 /// 将对象以二进制形式存储到硬盘中。
59 /// </summary>
60 /// <param name="objectToSave">用于保存的对象。</param>
61 /// <param name="path">文件路径。</param>
62 /// <returns>如果存储成功则返回true,否则返回false。</returns>
63 public static bool SaveAsBinary(object objectToSave, string path)
64 {
65 if (objectToSave != null && CanBinarySerialize)
66 {
67 byte[] ba = ConvertToBytes(objectToSave);
68 if (ba != null)
69 {
70 using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
71 {
72 using (BinaryWriter bw = new BinaryWriter(fs))
73 {
74 bw.Write(ba);
75 return true;
76 }
77 }
78 }
79 }
80 return false;
81 }
82 /**//// <summary>
83 ///将对象转化为XML格式文件,该对象必须用[Serialize]标记,否则将抛出错误。
84 /// </summary>
85 /// <param name="objectToConvert">用于序列化的标记。</param>
86 /// <returns>返回XML文本,如果对象为空则返回null。</returns>
87 public static string ConvertToString(object objectToConvert)
88 {
89 string xml = null;
90
91 if (objectToConvert != null)
92 {
93 //获取当前序列化对象。
94 Type t = objectToConvert.GetType();
95
96 XmlSerializer ser = new XmlSerializer(t);
97 //将序列化的结果保存到XML中。
98 using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture))
99 {
100 ser.Serialize(writer, objectToConvert);
101 xml = writer.ToString();
102 writer.Close();
103 }
104 }
105
106 return xml;
107 }
108 /**//// <summary>
109 /// 将对象序列化后以XML格式存储于文件中。
110 /// </summary>
111 /// <param name="objectToConvert">用于序列化的对象。</param>
112 /// <param name="path">用于存储的文件路径。</param>
113 public static void SaveAsXML(object objectToConvert, string path)
114 {
115 if (objectToConvert != null)
116 {
117 Type t = objectToConvert.GetType();
118
119 XmlSerializer ser = new XmlSerializer(t);
120
121 using (StreamWriter writer = new StreamWriter(path))
122 {
123 ser.Serialize(writer, objectToConvert);
124 writer.Close();
125 }
126 }
127
128 }
129 /**//// <summary>
130 /// 将一个二进制的数组转化为对象,必须通过类型转化自己想得到的相应对象。如果数组为空则返回空。
131 /// </summary>
132 /// <param name="byteArray">用于转化的二进制数组。</param>
133 /// <returns>返回转化后的对象实例,如果数组为空,则返回空对象。</returns>
134 public static object ConvertToObject(byte[] byteArray)
135 {
136 object convertedObject = null;
137 if (CanBinarySerialize && byteArray != null && byteArray.Length > 0)
138 {
139 BinaryFormatter binaryFormatter = new BinaryFormatter();
140 using (MemoryStream ms = new MemoryStream())
141 {
142 ms.Write(byteArray, 0, byteArray.Length);
143
144 ms.Position = 0;
145
146 if (byteArray.Length > 4)
147 convertedObject = binaryFormatter.Deserialize(ms);
148
149 ms.Close();
150 }
151 }
152 return convertedObject;
153 }
154 /**//// <summary>
155 /// 将文件的数据转化为对象。
156 /// </summary>
157 /// <param name="path">文件路径。</param>
158 /// <param name="objectType">希望得到的对象。</param>
159 /// <returns>返回反序列化的对象。</returns>
160 public static object ConvertFileToObject(string path, Type objectType)
161 {
162 object convertedObject = null;
163
164 if (path != null && path.Length > 0)
165 {
166 using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
167 {
168 XmlSerializer ser = new XmlSerializer(objectType);
169 convertedObject = ser.Deserialize(fs);
170 fs.Close();
171 }
172 }
173 return convertedObject;
174 }
175 /**//// <summary>
176 /// 将XML格式的字符串反序列化为实例对象。
177 /// </summary>
178 /// <param name="xml">Xml格式字符串。</param>
179 /// <param name="objectType">反序列化后所期望的对象。</param>
180 /// <returns>反序列化后所期望的对象,如果字符串为空,则返回空对象。</returns>
181 public static object ConvertToObject(string xml, Type objectType)
182 {
183 object convertedObject = null;
184
185 if (!WebHelper.IsNullOrEmpty(xml))
186 {
187 using (StringReader reader = new StringReader(xml))
188 {
189 XmlSerializer ser = new XmlSerializer(objectType);
190 convertedObject = ser.Deserialize(reader);
191 reader.Close();
192 }
193 }
194 return convertedObject;
195 }
196 /**//// <summary>
197 /// 将XML节点反序列化为实例对象。
198 /// </summary>
199 /// <param name="xml">用于反序列化的XML节点。</param>
200 /// <param name="objectType">反序列化后所期望的对象。</param>
201 /// <returns>反序列化后所期望的对象,如果字符串为空,则返回空对象。</returns>
202 public static object ConvertToObject(XmlNode node, Type objectType)
203 {
204 object convertedObject = null;
205
206 if (node != null)
207 {
208 using (StringReader reader = new StringReader(node.OuterXml))
209 {
210
211 XmlSerializer ser = new XmlSerializer(objectType);
212
213 convertedObject = ser.Deserialize(reader);
214
215 reader.Close();
216 }
217 }
218 return convertedObject;
219 }
220 /**//// <summary>
221 /// 加载一个二进制文件并将其转化为实例对象。
222 /// </summary>
223 /// <param name="path">文件路径。</param>
224 /// <returns>返回转化后的实例对象。</returns>
225 public static object LoadBinaryFile(string path)
226 {
227 if (!File.Exists(path))
228 return null;
229
230 using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
231 {
232 BinaryReader br = new BinaryReader(fs);
233 byte[] ba = new byte[fs.Length];
234 br.Read(ba, 0, (int)fs.Length);
235 return ConvertToObject(ba);
236 }
237 }
238 /**//// <summary>
239 /// 将字符串序列化<see cref="System.Collections.Specialized.NameValueCollection"/>类型,第一个为键,第二位与其相对应的值。
240 /// </summary>
241 /// <param name="keys">NameValueCollection中的keys键。</param>
242 /// <param name="values">NameValueCollection中的keys键对应的value。</param>
243 /// <returns>基于key-value格式的NameValeCollection集合对象。</returns>
244 /// <example>
245 /// string keys = "key1:S:0:3:key2:S:3:2:";
246 /// string values = "12345";
247 /// 则这个所得的NameValueCollection结果中包含两个键(key1和key2),他们所对应的值分别为(123和45)。
248 /// 其中:"key1:S:0:3"的key1表示键,S表示字符类型,0表示values起始的位置,3表示values结束的位置。
249 /// </example>
250 public static NameValueCollection ConvertToNameValueCollection(string keys, string values)
251 {
252 NameValueCollection nvc = new NameValueCollection();
253
254 if (keys != null && values != null && keys.Length > 0 && values.Length > 0)
255 {
256 char[] splitter = new char[1] { ':' };
257 string[] keyNames = keys.Split(splitter);
258
259 for (int i = 0; i < (keyNames.Length / 4); i++)
260 {
261 int start = int.Parse(keyNames[(i * 4) + 2], CultureInfo.InvariantCulture);
262 int len = int.Parse(keyNames[(i * 4) + 3], CultureInfo.InvariantCulture);
263 string key = keyNames[i * 4];
264
265 //Future version will support more complex types
266 if (((keyNames[(i * 4) + 1] == "S") && (start >= 0)) && (len > 0) && (values.Length >= (start + len)))
267 {
268 nvc[key] = values.Substring(start, len);
269 }
270 }
271 }
272
273 return nvc;
274 }
275 /**//// <summary>
276 /// 基于NameValueCollection对象序列化成keys和values的字符串。
277 /// </summary>
278 /// <param name="nvc">用于序列化的NameValueCollection对象。</param>
279 /// <param name="keys">ref格式的参数keys将转化为NameValueCollection中的key。</param>
280 /// <param name="values">ref格式的参数values将转化为NameValueCollection中的value。</param>
281 public static void ConvertFromNameValueCollection(NameValueCollection nvc, ref string keys, ref string values)
282 {
283 if (nvc == null || nvc.Count == 0)
284 return;
285
286 StringBuilder sbKey = new StringBuilder();
287 StringBuilder sbValue = new StringBuilder();
288
289 int index = 0;
290 foreach (string key in nvc.AllKeys)
291 {
292 if (key.IndexOf(':') != -1)
293 throw new ArgumentException("ExtendedAttributes Key can not contain the character \":\"");
294
295 string v = nvc[key];
296 if (!WebHelper.IsNullOrEmpty(v))
297 {
298 sbKey.AppendFormat("{0}:S:{1}:{2}:", key, index, v.Length);
299 sbValue.Append(v);
300 index += v.Length;
301 }
302 }
303 keys = sbKey.ToString();
304 values = sbValue.ToString();
305 }
306 }
在SiteSettings.cs中可以发现有些属性加有[XmlIgnore]标记,这是在序列化和反序列化时对该属性都不起作用,如SettingsID等在数据库中都已经存在字段名。从代码中我们可以看到,将一个NameValueCollection集合序列化和反序列化,其实键和值对存储在一个结构中,这个结构就是:
1 public struct SerializerData
2 {
3 /**//// <summary>
4 /// 序列化NameValueCollection集合时用于保存Keys的字符串。
5 /// </summary>
6 public string Keys;
7 /**//// <summary>
8 /// 序列化NameValueCollection集合时用于保存Values的字符串。
9 /// </summary>
10 public string Values;
11 }
2 {
3 /**//// <summary>
4 /// 序列化NameValueCollection集合时用于保存Keys的字符串。
5 /// </summary>
6 public string Keys;
7 /**//// <summary>
8 /// 序列化NameValueCollection集合时用于保存Values的字符串。
9 /// </summary>
10 public string Values;
11 }
其他的源代码都有解释了,应该能搞懂里面的东西!