簡體   English   中英

序列化和反序列化為XML文件C#

[英]Serialization and Deserialization into an XML file, C#

我有以下代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication28
{
class Program
{

    static void Main()
    {
        List<string> 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<string> GetFilesRecursive(string b)
        {
            // 1.
            // Store results in the file results list.
            List<string> result = new List<string>();

            // 2.
            // Store a stack of our directories.
            Stack<string> stack = new Stack<string>();

            // 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#的初學者時,我希望能得到一些幫助,並且我在序列化和反序列化方面非常不穩定。 我在編碼時遇到很多麻煩。 有人能幫我嗎?

謝謝

對於任何在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<OuterCollection> 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<InnerCollection1> innerCollection1Stuff { get; set; }

            [XmlArray("innercollection2")]
            [XmlArrayItem("text", typeof(InnerCollection2))]
            public List<InnerCollection2> innerConnection2Stuff { get; set; }
        }

        [Serializable()]
        public partial class InnerCollection2
        {

            [XmlText()]
            public string text { get; set; }
        }

        public partial class InnerCollection1
        {

            [XmlText()]
            public int number { get; set; }
        }
}

您的結果是List<string> ,並且不能直接序列化。 您將不得不包裝它,這是一種最小的方法:

[Serializable]
class Filelist: List<string> {  }

然后(De)Serialization如下:

Filelist data = new Filelist(); // replaces List<string>

// 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的列表。 那是一個不同的問題。

此類自行序列化和反序列化。...希望有幫助。

 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<string> UIComponents { get; set; }
        public List<string> 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<string>(){
                "config1", "config2"
            };
            thisConfig.UIComponents = new List<string>(){
                "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的外觀。

無論您做什么,都將失去空的捕獲塊。 您將后悔吞下例外。 記錄它們或重新拋出它們。

幫助#1。 將代碼縮進四個空格,以便在此處發布時將其視為代碼。

2:擺脫try / catch塊,因為它將吞噬所有異常,包括您想知道的異常。

3:您是否嘗試過序列化結果? 請編輯您的問題以顯示您嘗試過的內容。 提示:使用XmlSerializer類。

對於xml序列化,您有幾種可能性:

  • 手動做
  • 如上所述使用XmlSerializer
  • 使用System.Xml.Serialization
  • 使用Linq轉Xml

在過去兩年,看到一個代碼示例這個答案。 在這里看到一些陷阱)

對於遞歸目錄訪問者,您可以考慮使其真正遞歸: 這是一些有趣的代碼示例。

這個問題就是這個問題。 我也有一個已發布的答案,也將對您有用:

如何序列化?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM