ฉันจะเริ่มต้นด้วยคำตอบการคัดลอกของ Ben Gripka:
public void Save(string FileName)
{
using (var writer = new System.IO.StreamWriter(FileName))
{
var serializer = new XmlSerializer(this.GetType());
serializer.Serialize(writer, this);
writer.Flush();
}
}
ฉันใช้รหัสนี้ก่อนหน้านี้ แต่ความจริงแสดงให้เห็นว่าวิธีนี้เป็นปัญหาเล็กน้อย โดยทั่วไปโปรแกรมเมอร์ส่วนใหญ่มักจะตั้งค่าให้เป็นอนุกรมในการบันทึกและยกเลิกการตั้งค่าตามลำดับเมื่อโหลด นี่คือสถานการณ์ในแง่ดี เมื่อการทำให้เป็นอนุกรมล้มเหลวเนื่องจากสาเหตุบางประการไฟล์ถูกเขียนบางส่วนไฟล์ XML ไม่สมบูรณ์และไม่ถูกต้อง ด้วยเหตุนี้การกำจัดซีเรียลไลซ์ XML จึงไม่ทำงานและแอปพลิเคชันของคุณอาจมีปัญหาเมื่อเริ่มต้น หากไฟล์มีขนาดไม่ใหญ่มากฉันขอแนะนำให้วัตถุอันดับเป็นอันดับแรกMemoryStream
จากนั้นให้เขียนสตรีมไปที่ไฟล์ กรณีนี้มีความสำคัญอย่างยิ่งหากมีการจัดลำดับที่กำหนดเองที่ซับซ้อน คุณไม่สามารถทดสอบทุกกรณี
public void Save(string fileName)
{
//first serialize the object to memory stream,
//in case of exception, the original file is not corrupted
using (MemoryStream ms = new MemoryStream())
{
var writer = new System.IO.StreamWriter(ms);
var serializer = new XmlSerializer(this.GetType());
serializer.Serialize(writer, this);
writer.Flush();
//if the serialization succeed, rewrite the file.
File.WriteAllBytes(fileName, ms.ToArray());
}
}
การดีซีเรียลไลซ์เซชันในสถานการณ์จริงควรนับด้วยไฟล์การทำให้เป็นอนุกรมที่เสียหายซึ่งเกิดขึ้นบ้างในบางครั้ง ฟังก์ชั่นโหลดของ Ben Gripka นั้นใช้ได้
public static [ObjectType] Load(string fileName)
{
using (var stream = System.IO.File.OpenRead(fileName))
{
var serializer = new XmlSerializer(typeof([ObjectType]));
return serializer.Deserialize(stream) as [ObjectType];
}
}
และมันอาจถูกห่อหุ้มด้วยสถานการณ์การกู้คืนบางอย่าง เหมาะสำหรับไฟล์การตั้งค่าหรือไฟล์อื่น ๆ ที่สามารถลบได้ในกรณีที่เกิดปัญหา
public static [ObjectType] LoadWithRecovery(string fileName)
{
try
{
return Load(fileName);
}
catch(Excetion)
{
File.Delete(fileName); //delete corrupted settings file
return GetFactorySettings();
}
}