sábado, 10 de mayo de 2008

Monitorización de directorios

.Net Framework tiene una clase especialmente útil, y además muy sencilla de usar, para la tarea de monitorizar los cambios producidos en los ficheros de un directorio. La clase en concreto es FileSystemWatcher y se encuentra situada en el namespace System.IO.

En este post vamos a ver un pequeño ejemplo de cómo utilizarla. Para ello he implementado una sencilla aplicación de consola en la que iremos viendo cómo se utilizan los diferentes métodos y propiedades de la clase.

Lo primero que tenemos que hacer es crear la instáncia de nuestro objeto FileSystemWatcher:

watcher = new System.IO.FileSystemWatcher(); //el objeto ya ha sido declarado previamente

La primera propiedad que necesitamos establecer para nuestro objeto es Path. Obviamente indica el directorio que se quiere monitorizar:

watcher.Path = directory; //directory contiene el directorio a monitorozar, por ejemplo "C:/"


Con la propiedad IncludeSubdirectories indicamos si se quiere monitorizar o no tambien los subdirectorios del directorio indicado.
watcher.IncludeSubdirectories = true;

En este punto tenemos un directorio que está siendo monitorizado, el siguiente paso es indicar que tipo de modificaciones queremos que se nos notifiquen. Para ello tenemos varios eventos a los cuales hay que suscribirse:

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

Estos eventos serán lanzados por nuestro objeto cada vez que un ficchero sea borrado, renombrado ,creado o modificado respectivamente. En el método que captura el evento debemos realizar el tratamiento oportuno para cada uno de los casos.
La clase FileSystemWatcher tiene una propiedad que permite especificar para que tipo de cambios queremos que el evento Changed sea lanzado:

watcher.NotifyFilter = System.IO.NotifyFilters.FileName | System.IO.NotifyFilters.DirectoryName | System.IO.NotifyFilters.LastWrite | System.IO.NotifyFilters.Size;

En este ejemplo saltaria el evento cada vez que cambiara el nombre del archivo, el nombre del directorio, la ultima fecha de modificación del fichero o su tamaño.

Si la propiedad se deja en blanco, cualquier modificación hecha en el fichero provoca que el evento sea lanzado.

Aparte de los eventos de notificación existe otro evento que es lanzado cuando se produce algún tipo de error en la monitorización:

watcher.Error += new System.IO.ErrorEventHandler(watcher_Error);

En la función que captura el evento se puede acceder a la excepción que ha provocado el error.

Si ahora mismo ejecutasemos una aplicación con el código que hemos ido viendo (añadiendo las funciones de captura de los eventos y el tratamiento de estos por supuesto), comprobariamos que no se notifica ningún tipo de cambio por mas que borremos , creeemos o modifiquemos archivos. Esto es así porque nos falta establecer el valor de una propiedad, la propiedad EnableRaisingEvents. Si establecemos el valor de esta propiedad a cierto veremos como nuestra clase watcher lanza un evneto cada vez que se modifica algun fichero del directorio. De hecho esta propiedad puede utilizarse como interruptor para iniciar o detener la monitorización del directorio. Estableciendo la propiedad y ejecutando nuestra aplicación veremos cómo efectivamente funciona correctamente:

watcher.EnableRaisingEvents = true;


Con esto tenemos suficiente para monitorizar cualquier directorio o arbol de directorios. Aunque hay otras propiedades de la clase que no hemos mencionado y que pueden ser de utilidad:

  • Filter : Permite establecer un filtro para los ficheros que se quieren monitorizar. Por ejemplo -> "*.bmp" únicamente monitorizaríamos archivos con la extensión bmp.
  • InternalBufferSize : Permite establecer el valor del buffer del objeto FileSystemWatcher.
Combinando todas estas propiedades y eventos podemos realizar casi cualquier tipo de monitorización de directorios, editándonos por ejemplo el tan utilizado método de utilizar timers para ir comprobando si llegan archivos a un directorio determinado, etc...

Descargar código fuente del ejemplo

No hay comentarios: