Usar o 'FileSystemWatcher' para monitorizar uma pasta

estou a usar uma aplicação do Windows Forms para monitorizar um directório e mover os ficheiros largados para outro directório.

no momento ele irá copiar o arquivo para outro diretório, mas quando outro arquivo é adicionado ele vai apenas terminar sem mensagem de erro. Às vezes copia dois arquivos antes de terminar no terceiro.

Isto é porque estou a usar uma aplicação do formulário do Windows em vez de uma aplicação do console? Há alguma maneira de impedir o programa de terminar e de continuar a ver o directório?

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

O problema eram os filtros de notificação. O programa estava tentando abrir um arquivo que ainda estava copiando. Removi todos os filtros de notificação, excepto a 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, 2013-03-06 16:06:29

Você não forneceu o código de tratamento de arquivos, mas eu assumo que você cometeu o mesmo erro que todos fazem ao escrever pela primeira vez tal coisa: o evento filewatcher será levantado assim que o arquivo é criado. No entanto, levará algum tempo para que o arquivo seja concluído. Veja um tamanho de arquivo de 1 GB, por exemplo. O arquivo pode ser criado por outro programa (Explorer.exe copiá-lo de algum lugar) mas levará minutos para terminar esse processo. O evento é criado no momento da criação e você precisa espere que o arquivo esteja pronto para ser copiado.

Você pode esperar que um arquivo esteja pronto usando Esta função em um loop.

 20
Author: nvoigt, 2017-05-23 12:18:17
{[[2]} a razão pode ser que o observador é declarado como variável local para um método e é lixo coletado quando o método termina. Devias declará-lo como membro de classe. Tente o seguinte:
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, 2015-08-13 08:57:43