Uso de FileSystemWatcher para supervisar un directorio


Estoy usando una aplicación de Windows Forms para monitorear un directorio y mover los archivos que se dejan caer en él a otro directorio.

Por el momento copiará el archivo a otro directorio, pero cuando se agregue otro archivo, simplemente terminará sin mensaje de error. A veces copia dos archivos antes de terminar en el tercero.

¿Es porque estoy usando una aplicación de formulario de Windows en lugar de una aplicación de consola? ¿Hay alguna manera de que pueda detener el programa de terminar y seguir viendo el directorio?

private void watch()
{
  FileSystemWatcher watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}
Author: Neolisk, 2013-02-22

3 answers

El problema fueron los filtros de notificación. El programa estaba tratando de abrir un archivo que todavía estaba copiando. Eliminé todos los filtros de notificación excepto LastWrite.

private void watch()
{
  FileSystemWatcher watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastWrite;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}
 106
Author: cheeseman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-06 16:06:29

No suministró el código de manejo de archivos, pero asumo que cometió el mismo error que todo el mundo al escribir por primera vez tal cosa: el evento filewatcher se generará tan pronto como se cree el archivo. Sin embargo, tomará algún tiempo para que el archivo se termine. Tome un tamaño de archivo de 1 GB por ejemplo. El archivo puede ser creado por otro programa (Explorer.exe copiándolo desde algún lugar) pero tomará minutos terminar ese proceso. El evento se plantea en el momento de la creación y hay que esperar a el archivo a estar listo para ser copiado.

Puede esperar a que un archivo esté listo usando esta función en un bucle.

 20
Author: nvoigt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:17

La razón puede ser que watcher se declara como variable local a un método y es basura recolectada cuando el método termina. Debe declararlo como miembro de la clase. Prueba lo siguiente:

FileSystemWatcher watcher;

private void watch()
{
  watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}
 16
Author: user1912419,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-13 08:57:43