sábado, 15 de mayo de 2010

Vigilar nuestro sistema de archivos con FileSystemWatcher

Hay una caracteristica del .net framework un tanto desconocida, la clase FileSystemWatcher que monitorea el sistema de archivos y dispara un evento cada vez que se realiza algun cambio.

Las aplicaciones de esta clase son muchísimas, todo depende del potencial que vayamos descubriendo.






Como primer paso creamos nuestro formulario en Visual Studio.


Declaramos nuestro objeto del tipo FileSystemWatcher:
System.IO.FileSystemWatcher watcher;

Definimos los eventos cuando se presiona el boton "Iniciar"
        private void buttonIniciar_Click(object sender, EventArgs e)
        {
            watcher.Path = textBoxPath.Text;    //Se define la carpeta que se va a monitorear
            watcher.IncludeSubdirectories = checkBoxSubDir.Checked; // true: se monitorean todos los subdirectorios

            /*  EVENTOS GENERADOS   */
            watcher.Changed += new System.IO.FileSystemEventHandler(watcher_Changed);  
            watcher.Renamed += new System.IO.RenamedEventHandler(watcher_Renamed);
            watcher.Deleted += new System.IO.FileSystemEventHandler(watcher_Deleted);
            watcher.Created += new System.IO.FileSystemEventHandler(watcher_Created);

            watcher.EnableRaisingEvents = true;
            buttonDetener.Enabled = true;
            buttonIniciar.Enabled = false;
        }

Y posteriormente controlamos las funciones que se ejecutan al dispararse el evento (para este ejemplo únicamente escribimos en un textbox los cambios que se han realizado):

        void watcher_Created(object sender, System.IO.FileSystemEventArgs e)
        {
                textBoxLog.Text += e.ChangeType + ":" + e.FullPath + Environment.NewLine;
        }

        void watcher_Deleted(object sender, System.IO.FileSystemEventArgs e)
        {
                textBoxLog.Text += e.ChangeType + ":" + e.FullPath + Environment.NewLine;
        }

        void watcher_Renamed(object sender, System.IO.RenamedEventArgs e)
        {
                textBoxLog.Text += e.ChangeType + " >> " + e.OldFullPath + ":" + e.FullPath + Environment.NewLine;
        }

        void watcher_Changed(object sender, System.IO.FileSystemEventArgs e)
        {
                textBoxLog.Text += e.ChangeType + ":" + e.FullPath + Environment.NewLine;
        }

Si asi lo deseamos podemos disponer de un boton "Detener":

        private void buttonDetener_Click(object sender, EventArgs e)
        {
            watcher.Changed -= new System.IO.FileSystemEventHandler(watcher_Changed);
            watcher.Renamed -= new System.IO.RenamedEventHandler(watcher_Renamed);
            watcher.Deleted -= new System.IO.FileSystemEventHandler(watcher_Deleted);
            watcher.Created -= new System.IO.FileSystemEventHandler(watcher_Created);
            watcher.EnableRaisingEvents = true;
            buttonIniciar.Enabled = true;
            buttonDetener.Enabled = false;
        }


Filtros

La propieda filter de nuestro objeto FileSystemWatcher nos permite definir que tipo de archivos queremos monitorear, en la vida real un filtro del tipo "*.*" no sirve ya que siempre se realizan cambios en los archivos en segundo plano (archivos pueden no interesarnos).

Nota al margen: En máquina con Windows XP (sin Service Pack) y anteriores sólo funciona un objeto FileSystemWatcher a la vez sobre el mismo folder, mientras que en máquinas con Windows XP SP 1 o superiores se pueden tener dos o mas instancias de la clase FileSystemWatcher a la vez.

1 comentario: