[英]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類。
這個問題就是這個問題。 我也有一個已發布的答案,也將對您有用:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.