2015-06-08 9 views
7

Ich versuche, ein Array von FileInfo- und DirectoryInfo-Objekten zur Verwendung als Protokolldatei zu speichern. Ziel ist es, ein Bild eines Verzeichnisses (und von Unterverzeichnissen) zu einem Zeitpunkt für einen späteren Vergleich zu erfassen. Ich bin derzeit mit dieser Klasse die Informationen zu speichern:FileSystemInfo-Array in Datei speichern

public class myFSInfo 
{ 
    public FileSystemInfo Dir; 
    public string RelativePath; 
    public string BaseDirectory; 
    public myFSInfo(FileSystemInfo dir, string basedir) 
    { 
     Dir = dir; 
     BaseDirectory = basedir; 
     RelativePath = Dir.FullName.Substring(basedir.Length + (basedir.Last() == '\\' ? 1 : 2)); 
    } 
    private myFSInfo() { } 
    /// <summary> 
    /// Copies a FileInfo or DirectoryInfo object to the specified path, creating folders and overwriting if necessary. 
    /// </summary> 
    /// <param name="path"></param> 
    public void CopyTo(string path) 
    { 
     if (Dir is FileInfo) 
     { 
      var f = (FileInfo)Dir; 
      Directory.CreateDirectory(path.Substring(0,path.LastIndexOf("\\"))); 
      f.CopyTo(path,true); 
     } 
     else if (Dir is DirectoryInfo) Directory.CreateDirectory(path); 
    } 
} 

ich versucht habe, XML und Binary meine Klasse ohne Glück Serialisierung. Ich habe auch versucht, eine neue Klasse zu schaffen, die nicht die tatsächliche Fileinfo enthält, sondern nur Attribute ausgewählt:

public class myFSModInfo 
{ 
    public Type Type; 
    public string BaseDirectory; 
    public string RelativePath; 
    public string FullName; 
    public DateTime DateModified; 
    public DateTime DateCreated; 
    public myFSModInfo(FileSystemInfo dir, string basedir) 
    { 
     Type = dir.GetType(); 
     BaseDirectory = basedir; 
     RelativePath = dir.FullName.Substring(basedir.Length + (basedir.Last() == '\\' ? 1 : 2)); 
     FullName = dir.FullName; 
     DateModified = dir.LastWriteTime; 
     DateCreated = dir.CreationTime; 
    } 
    private myFSModInfo() { } 
    /// <summary> 
    /// Copies a FileInfo or DirectoryInfo object to the specified path, creating folders and overwriting if necessary. 
    /// </summary> 
    /// <param name="path"></param> 
    public void CopyTo(string path) 
    { 
     if (Type == typeof(FileInfo)) 
     { 
      Directory.CreateDirectory(path.Substring(0, path.LastIndexOf("\\"))); 
      File.Copy(FullName,path, true); 
     } 
     else if (Type == typeof(DirectoryInfo)) Directory.CreateDirectory(path); 
    } 
    public void Delete() 
    { 
     if (Type == typeof(FileInfo)) File.Delete(FullName); 
     else if (Type == typeof(DirectoryInfo)) Directory.Delete(FullName); 
    } 
} 

Ich hatte auch kein Glück dieser Serialisierung. Ich könnte die Fehler auflisten, die bei meinen verschiedenen Versuchen aufgetreten sind, aber es wäre wahrscheinlich einfacher, zuerst den besten Ansatz auszuwählen. Hier ist meine Serialisierungscode:

public void SaveLog(string savepath, string dirpath) 
    { 
     var dirf = new myFSModInfo[1][]; 
     string[] patharr = {dirpath}; 
     GetFSInfo(patharr, dirf); 

     var mySerializer = new System.Xml.Serialization.XmlSerializer(typeof(myFSModInfo[])); 
     var myWriter = new StreamWriter(savepath); 
     mySerializer.Serialize(myWriter, dirf[0]); 
     myWriter.Close(); 

     /*var bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 
     FileStream fs = new FileStream(savepath, FileMode.Create, FileAccess.Write); 
     bf.Serialize(fs, dirf[0]); */ 
    } 
+4

Denken Sie nur Eigenschaften serialisiert werden können, keine Variablen. –

+0

Kannst du etwas konkreteres zu deinen Problemen geben? – Octopoid

+1

haben Sie die Klasse als serialisierbar deklariert? [Serializable] – Sorceri

Antwort

5

Filesysteminfo ist nicht serialisierbar, weil es kein simple type ist. FileInfo ist nicht serialisierbar, da es keine leere default constructor enthält.

Wenn Sie also diese Informationen speichern möchten, müssen Sie Ihre eigene Klasse mit einfachen Typen erstellen, die die Informationen aus FileInfo oder FileSystemInfo umhüllen.

[Serializable] 
public class MyFileInfo 
{ 
    public string Name { get; set; } 

    public long Length { get; set;} 

    /// <summary> 
    /// An empty ctor is needed for serialization. 
    /// </summary> 
    public MyFileInfo(){ 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="test.MyFileInfo"/> class. 
    /// </summary> 
    /// <param name="fileInfo">File info.</param> 
    public MyFileInfo(string path) 
    { 
     FileInfo fileInfo = new FileInfo (path); 
     this.Length = fileInfo.Length; 
     this.Name = fileInfo.Name; 
     // TODO: add and initilize other members 
    } 
} 

Beispiel Nutzung:

List<MyFileInfo> list = new List<MyFileInfo>(); 

foreach (string entry in Directory.GetFiles(@"c:\temp")) 
{ 
    list.Add (new MyFileInfo (entry)); 
} 

XmlSerializer xsSubmit = new XmlSerializer(typeof(List<MyFileInfo>)); 
StringWriter sww = new StringWriter(); 
XmlWriter writer = XmlWriter.Create(sww); 
xsSubmit.Serialize(writer, list); 

Console.WriteLine (sww.ToString()); 
+0

Danke ec8or. Ich erkannte nach dem Lesen Ihrer Antwort, dass ich versehentlich den ersten Codeblock wiederholt hatte, anstatt meinen zweiten Klassenversuch zu posten. Das habe ich jetzt behoben. Es entspricht dem, was Sie vorschlagen, aber ich erhalte diesen Fehler: "System.InvalidOperationException: System.RuntimeType ist aufgrund seiner Schutzstufe nicht zugänglich. Nur öffentliche Typen können verarbeitet werden." –

+0

Einige Zugriffsmodifizierer sind wahrscheinlich falsch. Stellen Sie sicher, dass die Klasse, die Sie serialisieren möchten, öffentlich ist. Wenn es komplexe Eigenschaften hat, müssen sie auch einen öffentlichen Typ haben. Wenn Sie eine Eigenschaft ignorieren möchten, müssen Sie die [XmlIgnore] -Attribute verwenden. – komaflash

+0

Sie können meine Klasse im 2. Codeblock oben sehen. Ich glaube, ich machte beides öffentlich. Ich möchte kein Attribut ignorieren, da ich nur Attribute in diese Klasse einbeziehe. In meiner ersten Klasse habe ich ein FileSystemInfo-Objekt eingefügt, das Attribute enthält, die ich ignorieren könnte, aber der XMLSerializer mag FileInfo nicht. Ich habe das Serializable-Tag hinzugefügt, aber immer noch kein Glück. Irgendeine Idee, was das Problem ist? –