120 votes

Utilisation de FileSystemWatcher pour surveiller un répertoire

J'utilise une application Windows Forms pour surveiller un répertoire et déplacer les fichiers qui s'y trouvent vers un autre répertoire.

Pour le moment, il copie le fichier dans un autre répertoire, mais lorsqu'un autre fichier est ajouté, il se termine simplement sans message d'erreur. Parfois, il copie deux fichiers avant de s'arrêter au troisième.

Est-ce parce que j'utilise une application Windows Form plutôt qu'une application console ? Existe-t-il un moyen d'empêcher le programme de se terminer et de continuer à surveiller le répertoire ?

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

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

public void Dispose()
{
  // avoiding resource leak
  watcher.Changed -= OnChanged;
  this.watcher.Dispose();
}

161voto

cheeseman Points 3327

Le problème était les filtres de notification. Le programme essayait d'ouvrir un fichier qui était toujours en cours de copie. J'ai supprimé tous les filtres de notification sauf le 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;
}

34voto

nvoigt Points 20484

Vous n'avez pas fourni le code de gestion du fichier, mais je suppose que vous avez fait la même erreur que tout le monde lors de la première écriture de ce genre de chose : l'événement filewatcher sera levé dès que le fichier sera créé. Cependant, il faudra un certain temps pour que le fichier soit terminé. Prenons l'exemple d'un fichier de 1 Go. Le fichier peut être créé par un autre programme (Explorer.exe le copiant de quelque part) mais il faudra des minutes pour que ce processus se termine. L'événement est déclenché au moment de la création et vous devez attendre que le fichier soit prêt à être copié.

Vous pouvez attendre qu'un fichier soit prêt en utilisant l'option este dans une boucle.

27voto

user1912419 Points 476

La raison peut en être que le watcher est déclaré comme une variable locale d'une méthode et qu'il est récupéré à la fin de la méthode. Vous devriez le déclarer comme un membre de la classe. Essayez ce qui suit :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X