序列化和反序列化为XML文件,C#

我有以下代码:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace ConsoleApplication28 { class Program { static void Main() { List dirs = FileHelper.GetFilesRecursive(@"c:\Documents and Settings\bob.smith\Desktop\Test"); foreach (string p in dirs) { Console.WriteLine(p); } //Write Count Console.WriteLine("Count: {0}", dirs.Count); Console.Read(); } static class FileHelper { public static List GetFilesRecursive(string b) { // 1. // Store results in the file results list. List result = new List(); // 2. // Store a stack of our directories. Stack stack = new Stack(); // 3. // Add initial directory. stack.Push(b); // 4. // Continue while there are directories to process while (stack.Count > 0) { // A. // Get top directory string dir = stack.Pop(); try { // B // Add all files at this directory to the result List. result.AddRange(Directory.GetFiles(dir, "*.*")); // C // Add all directories at this directory. foreach (string dn in Directory.GetDirectories(dir)) { stack.Push(dn); } } catch { // D // Could not open the directory } } return result; } } } } 

上面的代码适用于递归查找我的c:上的文件夹中的文件/目录。
我试图将此代码的结果序列化为XML文件,但我不知道如何执行此操作。

我的项目是:找到驱动器中的所有文件/目录,序列化为XML文件。 然后,第二次运行这个应用程序,我将有两个XML文件进行比较。 然后,我想从第一次运行此应用程序时反序列化XML文件,并将差异与当前XML文件进行比较,并生成更改报告(即已添加,删除,更新的文件)。

我希望得到一些帮助,因为我是C#的初学者,我在序列化和反序列化方面非常不稳定。 我编码时遇到了很多麻烦。 有人能帮我吗?

谢谢

您的结果是List ,并且不能直接序列化。 你必须包装它,一个最小的方法:

 [Serializable] class Filelist: List { } 

然后(De)序列化就像:

 Filelist data = new Filelist(); // replaces List // fill it using (var stream = File.Create(@".\data.xml")) { var formatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter(); formatter.Serialize(stream, data); } data = null; // lose it using (var stream = File.OpenRead(@".\data.xml")) { var formatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter(); data = (Filelist) formatter.Deserialize(stream); } 

但请注意,您不会以任何方式比较XML(不实用)。 您将比较(反序列化)List实例。 并且XML是SOAP格式的,看看它。 它在另一种情况下可能不是很有用。

因此,您可以轻松使用不同的Formatter(二进制文件更有效,更灵活)。

或者您可能只想将文件列表保存为XML。 这是一个不同的问题。

对于任何遇到xml序列化和反序列化问题的人。 我已经创建了一个示例类来执行此操作。 它也适用于递归集合(如文件和目录)。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Sample { [Serializable()] [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false, ElementName = "rootnode")] public partial class RootNode { [System.Xml.Serialization.XmlElementAttribute("collection1")] public List OuterCollections { get; set; } } [Serializable()] public partial class OuterCollection { [XmlAttribute("attribute1")] public string attribute1 { get; set; } [XmlArray(ElementName = "innercollection1")] [XmlArrayItem("text", Type = typeof(InnerCollection1))] public List innerCollection1Stuff { get; set; } [XmlArray("innercollection2")] [XmlArrayItem("text", typeof(InnerCollection2))] public List innerConnection2Stuff { get; set; } } [Serializable()] public partial class InnerCollection2 { [XmlText()] public string text { get; set; } } public partial class InnerCollection1 { [XmlText()] public int number { get; set; } } } 

这个类序列化和反序列化….希望这有帮助。

  using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Xml.Serialization; using System.Xml; namespace TestStuff { public class Configuration { #region properties public List UIComponents { get; set; } public List Settings { get; set; } #endregion //serialize itself public string Serialize() { MemoryStream memoryStream = new MemoryStream(); XmlSerializer xs = new XmlSerializer(typeof(Configuration)); using (StreamWriter xmlTextWriter = new StreamWriter(memoryStream)) { xs.Serialize(xmlTextWriter, this); xmlTextWriter.Flush(); //xmlTextWriter.Close(); memoryStream = (MemoryStream)xmlTextWriter.BaseStream; memoryStream.Seek(0, SeekOrigin.Begin); StreamReader reader = new StreamReader(memoryStream); return reader.ReadToEnd(); } } //deserialize into itself public void Deserialize(string xmlString) { String XmlizedString = null; using (MemoryStream memoryStream = new MemoryStream()) { using (StreamWriter w = new StreamWriter(memoryStream)) { w.Write(xmlString); w.Flush(); XmlSerializer xs = new XmlSerializer(typeof(Configuration)); memoryStream.Seek(0, SeekOrigin.Begin); XmlReader reader = XmlReader.Create(memoryStream); Configuration currentConfig = (Configuration)xs.Deserialize(reader); this.Settings = currentConfig.Settings; this.UIComponents = currentConfig.UIComponents; w.Close(); } } } static void Main(string[] args) { Configuration thisConfig = new Configuration(); thisConfig.Settings = new List(){ "config1", "config2" }; thisConfig.UIComponents = new List(){ "comp1", "comp2" }; //serializing the object string serializedString = thisConfig.Serialize(); Configuration myConfig = new Configuration(); //deserialize into myConfig object myConfig.Deserialize(serializedString); } } } 

约翰:

我可以建议改进吗? 而不是使用文件名,使用FileInfo对象 。 这将允许您获得有关每个文件的更准确的信息,而不仅仅是它是否存在于同一名称下。

此外,XmlSerializer类应该没问题。 它不会序列化通用列表,因此您必须将List <>输出到数组或其他类似的数组,但除此之外:

  XmlSerializer serial = new XmlSerializer(typeof(FileInfo[])); StringWriter writer = new StringWriter(); FileInfo[] fileInfoArray = GetFileInfos(); serial.Serialize(writer, fileInfoArrays); 

除非对序列化XML的外观如何重要,否则简单易行。

无论你做什么,都要失去空挡块。 你会后悔吞下exception。 记录它们或重新扔它们。

帮助#1。 将代码缩进四个空格,以便在此处发布时将其视为代码。

2:摆脱那个try / catch块,因为它会吃掉所有exception,包括你想知道的exception。

3:您是否完全尝试将结果序列化? 请编辑您的问题以显示您尝试的内容。 提示:使用XmlSerializer类。

对于xml序列化,您有几种可能性:

  • 手动完成
  • 如上所述使用XmlSerializer
  • 使用System.Xml.Serialization
  • 使用Linq到Xml

对于最后两个,请参阅此答案中的代码示例。 (看到这里的一些问题 )

对于递归目录访问者,您可以考虑使其真正递归: 这是一些有趣的代码示例。

这个问题就像这个问题。 我也有一个贴出的答案,对你也有用:

如何序列化?