面试题答案
一键面试使用XmlSerializer和JsonSerializer进行序列化和反序列化
- XmlSerializer序列化
using System.IO; using System.Xml.Serialization; public static void SerializeToXml<T>(T obj, string filePath) { var serializer = new XmlSerializer(typeof(T)); using (var writer = new StreamWriter(filePath)) { serializer.Serialize(writer, obj); } }
- XmlSerializer反序列化
public static T DeserializeFromXml<T>(string filePath) { var serializer = new XmlSerializer(typeof(T)); using (var reader = new StreamReader(filePath)) { return (T)serializer.Deserialize(reader); } }
- JsonSerializer序列化(从.NET 5.0起)
using System.IO; using System.Text.Json; public static void SerializeToJson<T>(T obj, string filePath) { var options = new JsonSerializerOptions { WriteIndented = true }; var jsonString = JsonSerializer.Serialize(obj, options); File.WriteAllText(filePath, jsonString); }
- JsonSerializer反序列化(从.NET 5.0起)
public static T DeserializeFromJson<T>(string filePath) { var jsonString = File.ReadAllText(filePath); return JsonSerializer.Deserialize<T>(jsonString); }
处理大型复杂结构时的性能问题
- 内存占用:在反序列化大型复杂结构时,可能会导致大量的内存占用。例如,
XmlSerializer
和JsonSerializer
在解析数据时,会一次性将整个数据结构加载到内存中,对于超大型数据,可能会引发OutOfMemoryException
。 - 序列化/反序列化时间:复杂结构意味着更多的嵌套和属性,序列化和反序列化操作需要遍历大量的数据节点,这会导致操作时间变长,尤其是在处理包含大量元素的数组或多层嵌套对象时。
优化方案
- 流式处理
- XmlSerializer:可以使用
XmlReader
和XmlWriter
进行流式处理,避免一次性加载整个文档。例如:
using System.Xml; using System.Xml.Serialization; public static void SerializeToXmlStream<T>(T obj, Stream outputStream) { var serializer = new XmlSerializer(typeof(T)); using (var xmlWriter = XmlWriter.Create(outputStream)) { serializer.Serialize(xmlWriter, obj); } } public static T DeserializeFromXmlStream<T>(Stream inputStream) { var serializer = new XmlSerializer(typeof(T)); using (var xmlReader = XmlReader.Create(inputStream)) { return (T)serializer.Deserialize(xmlReader); } }
- JsonSerializer:从.NET 6.0起,可以使用
Utf8JsonWriter
和Utf8JsonReader
进行流式处理。例如:
using System.Text.Json; public static void SerializeToJsonStream<T>(T obj, Stream outputStream) { var options = new JsonSerializerOptions { WriteIndented = true }; using (var writer = new Utf8JsonWriter(outputStream, options)) { JsonSerializer.Serialize(writer, obj, typeof(T)); } } public static T DeserializeFromJsonStream<T>(Stream inputStream) { using (var reader = new Utf8JsonReader(inputStream)) { return JsonSerializer.Deserialize<T>(ref reader); } }
- XmlSerializer:可以使用
- 数据结构优化:尽量简化复杂的数据结构,减少不必要的嵌套层次。例如,如果存在多层嵌套数组,可以考虑扁平化处理,这样在序列化和反序列化时,遍历的数据节点会减少,提高性能。
- 缓存序列化器:对于特定类型的序列化和反序列化,可以缓存
XmlSerializer
和JsonSerializer
实例,避免重复创建,因为创建序列化器实例本身也有一定的性能开销。例如:private static readonly Dictionary<Type, XmlSerializer> xmlSerializerCache = new Dictionary<Type, XmlSerializer>(); private static readonly Dictionary<Type, JsonSerializerOptions> jsonSerializerOptionsCache = new Dictionary<Type, JsonSerializerOptions>(); public static XmlSerializer GetXmlSerializer<T>() { if (!xmlSerializerCache.TryGetValue(typeof(T), out var serializer)) { serializer = new XmlSerializer(typeof(T)); xmlSerializerCache.Add(typeof(T), serializer); } return serializer; } public static JsonSerializerOptions GetJsonSerializerOptions<T>() { if (!jsonSerializerOptionsCache.TryGetValue(typeof(T), out var options)) { options = new JsonSerializerOptions { WriteIndented = true }; jsonSerializerOptionsCache.Add(typeof(T), options); } return options; }