Blog Stats
  • Posts - 16
  • Articles - 0
  • Comments - 122
  • Trackbacks - 31

 

Sunday, July 15, 2007

[70-553] – 1. Section 1 – 3 Implementing serialization – 3 – Files and folders

Nella gestione dei file e delle directory, in  System.IO,  si utilizzano principalmente: File, FileInfo, Directory, Directory Info e la DriveInfo.  La DriveInfo è bella perchè da un sacco di informazioni sul disco:

          DriveInfo d = new DriveInfo("d:\\");

            String info = "Drive: " + d.Name +

                "Drive Format " + d.DriveFormat +

                "\nDrive Type " + d.DriveType +

                "\nVolume " + d.VolumeLabel +

                "\nTotal Size " + d.TotalSize.ToString() +

                "\nAvailable FreeSpace " + d.AvailableFreeSpace.ToString() +

                "\nTotal Free Space " + d.TotalFreeSpace.ToString();

            Console.WriteLine(info);

dove DriveType indica CDRom, Fixed, Network, Removable,Ram,.. e DriveFormat  dice NTFS or FAT32.

Interessante anche il FileSystemWatcher per le notifiche, su cui c’e’ anche un post di Mirko Gatti, http://blogs.ugidotnet.org/mitch/archive/2006/09/22/48513.aspx   . Confesso che con il framework 2.0 nei miei test questo non ho verificato l’errore in creazione, ma in un caso di copia di file.

Per giocare un po’ mi sono fatta una funzioncina di utilità che copia tutta una directory e assegna a tutti i file  e directory una certa data di creazione/ultima modifica. Questa me la metto in una console application e do’ il risultato il pasto al setup e ho tutte le cose belle ordinate. Magari c’e’ un’opzione da qualche parte che lo fa da solo, pero’ con questa ci posso poi mettere dei filtri e saltare alcuni tipi di file...

        private static void CopyAll(string from, string to, DateTime  date)

        {

            //dati delle directory di partenza

            DirectoryInfo dFrom = new DirectoryInfo(from);

            //dati delle directory di destinazione

            DirectoryInfo dTo = new DirectoryInfo(to);

 

            if (!dTo.Exists)

            {

                //ricreo la directory           

                System.IO.Directory.CreateDirectory(to);

                dTo.CreationTime = date;  //metto le date di creazione, modifica

                dTo.LastWriteTime = date;

            }

 

            //leggo tutti i file

            FileInfo[] files = dFrom.GetFiles();

            foreach (FileInfo f in files)

            {

                //copio il file

                string newFile = System.IO.Path.Combine(to, f.Name);

                System.IO.File.Copy(f.FullName, newFile );               

                FileInfo fNew = new FileInfo(newFile);

               

                //determino se è readonly

                bool bReadOnly = (fNew.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;

 

                //se è readonly .. tolgo l'attributo

                if (bReadOnly)   fNew.Attributes = fNew.Attributes ^ FileAttributes.ReadOnly; 

               

 fNew.CreationTime = f.CreationTime; //assegno data di creazione originale

                fNew.LastWriteTime = date; //assegno date di ultima modifiche/accesso

                fNew.LastAccessTime = date;

               

                //se occorre rimetto a posto il readonly

                if (bReadOnly)  fNew.Attributes = fNew.Attributes ^ FileAttributes.ReadOnly;  

            }

 

            //vado in ricorsione per le directory

            DirectoryInfo[] dir = dFrom.GetDirectories();

            foreach (DirectoryInfo d in dir)

                CopyAll(d.FullName, System.IO.Path.Combine(to, d.Name), date);

 

        }

 

Per completare il lavoro serve una funzione di DeleteAll della directory di destinazione, prima di iniziare la copia.

Se ci sono file ReadOnly non ci  si puo’ limitare ad usare dTo.Delete(true), viene un’eccezione.. occorre andare a togliere l’attributo.

[70-553] – 1. Section 1 – 3 Implementing serialization – 2 – Control Xml Serialization

Gioco  un po’ quello che c’e’ in System.Xml.Serialization, anche perchè in TV non c’e’ (al solito) nulla di umano da vedere... ed il resto (saggio) della famiglia dorme.

 

La classe per serializzare è XmlSerializer, che si avvale di una bella dose di attributi sulle proprietà delle classi , es.

XmlRootAttribute : elemento radice dell’oggetto

XmlElementAttribute = elemento xml classico

XmlAttributeAttribute= elemento di tipo attributo

E i suoi amici.. XmlTextAttribute, XmlTypeAttribute, XmlEnumAttribute.., XmlArray

(ci sono anche per soap e si chiamano SoapAttributeAttribute, SoapEnumAttribute....).

   [XmlRootAttribute("IlMioOggetto", Namespace = "http://www.bruna.com", IsNullable = false)]

    public class mioOggetto2

    {

        [XmlAttributeAttribute]

        public string id;

        [XmlElementAttribute( IsNullable = false, DataType="string"  )]

        public  string nome;       //se sono private non si serializzano       

        [XmlElementAttribute] //è cmq il default

        public string cognome;

        [XmlElementAttribute(ElementName="Eta", DataType="int")]

        public int eta;

        [XmlArray]

        public List<string> nipotini;

 

        public mioOggetto2()

        {

            // questo è necessario perchè altrimenti XmlSerializer si rifiuto di inizializarsi

        }

        public mioOggetto2(string n, string c, int e)

        {

            id = System.Guid.NewGuid().ToString();

            nome = n;

            nipotini = new List<string>();

            eta = e;

        }

        public  void addNipote(string nome) { nipotini.Add(nome); }

 }

 

E si utilizza in un bel xmlSerializer

        static void Main(string[] args)

        {

            mioOggetto2 obj1 = new mioOggetto2("Donald", "Duck");

            obj1.addNipote("Qui"); obj1.addNipote("Quo"); obj1.addNipote("Qua");

               

            XmlSerializer ser = new XmlSerializer(typeof(mioOggetto2));

            TextWriter txtW = new StreamWriter("c:\\temp\\serialize1.xml");

            ser.Serialize(txtW, obj1);

            txtW.Close();               

        }

Ed il risultato è:

<?xml version="1.0" encoding="utf-8" ?>

- <IlMioOggetto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="43e35b0b-e94f-47f7-a2eb-9e4db3c682e1" xmlns="http://www.bruna.com">

  <nome>Donald</nome>

  <Eta>0</Eta>

- <nipotini>

  <string>Qui</string>

  <string>Quo</string>

  <string>Qua</string>

  </nipotini>

  </IlMioOggetto>

 

 

E per rileggere? Nel main:

 

            XmlSerializer ser2 = new XmlSerializer(typeof(mioOggetto2));

            TextReader txtR = new StreamReader("c:\\temp\\serialize1.xml");

            mioOggetto2 m = (mioOggetto2) ser2.Deserialize(txtR);

 

E avro’ tutto a posto..

Un esempio molto bello,  c’e’ nell’MSDN  in c++ , nella classe XmlSerializer.

 

 

 

Copyright © Bruna Gavioli