2015-06-08 13 views
7

Sto tentando di salvare una serie di oggetti FileInfo e DirectoryInfo da utilizzare come file di registro. L'obiettivo è catturare un'immagine di una directory (e sottodirectory) in un momento specifico per un confronto successivo. Attualmente sto usando questa classe per memorizzare informazioni:Salvataggio della matrice FileSystemInfo su file

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); 
    } 
} 

Ho provato XML e binari serializzazione mia classe senza fortuna. Ho anche cercato di creare una nuova classe che non contiene l'attuale FileInfo ma solo selezionato attributi:

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); 
    } 
} 

ho anche avuto fortuna serializzazione questo. Potrei elencare gli errori che ho riscontrato con i miei vari tentativi, ma sarebbe probabilmente più facile selezionare prima l'approccio migliore. Qui è il mio codice di serializzazione:

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

pensa di poter serializzare solo le proprietà, non variabili. –

+0

Puoi fornire dettagli più specifici sui problemi che hai riscontrato? – Octopoid

+1

hai dichiarato la classe come serializzabile? [Serializable] – Sorceri

risposta

5

FileSystemInfo non è serializzabile, perché non è un simple type. FileInfo non è serializzabile, perché non ha default constructor vuoto.

Quindi, se si desidera salvare tali informazioni, è necessario creare la propria classe con tipi semplici, che avvolgono tali informazioni da FileInfo o FileSystemInfo.

[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 
    } 
} 

Esempio di utilizzo:

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

Grazie ec8or. Mi sono reso conto dopo aver letto la tua risposta che avevo erroneamente ripetuto il primo blocco di codice, invece di postare il mio tentativo di seconda classe. Ora l'ho risolto. È sulla falsariga di ciò che suggerisci, ma sto ricevendo questo errore: "System.InvalidOperationException: System.RuntimeType è inaccessibile a causa del relativo livello di protezione. Possono essere elaborati solo tipi pubblici." –

+0

Alcuni modificatori di accesso probabilmente non sono corretti. Assicurati che la classe che desideri serializzare sia pubblica. Se ha proprietà complesse, devono avere anche un tipo di pubblicazione visibile. Se si desidera ignorare alcune proprietà, è necessario utilizzare [XmlIgnore] -Attribute. – komaflash

+0

Puoi vedere la mia classe nel secondo blocco di codice sopra. Penso di averlo reso pubblico. Non voglio ignorare alcun attributo, dal momento che ho incluso solo gli attributi di cui ho bisogno in questa classe. Nella mia prima lezione, ho incluso un oggetto FileSystemInfo, che ha attributi che potrei ignorare, ma a XMLserializer non piace FileInfo. Ho aggiunto il tag Serializeable, ma ancora senza fortuna. Qualche idea di quale sia il problema? –