Notificação quando um arquivo muda?

112

Existe algum mecanismo pelo qual posso ser notificado (em C #) quando um arquivo é modificado no disco?

PaulB
fonte
1
Consulte esta resposta para obter mais informações sobre a classe FileSystemWatcher e os eventos que ela gera.
ChrisF

Respostas:

205

Você pode usar a FileSystemWatcherclasse.

public void CreateFileWatcher(string path)
{
    // Create a new FileSystemWatcher and set its properties.
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = path;
    /* Watch for changes in LastAccess and LastWrite times, and 
       the renaming of files or directories. */
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
       | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    // Only watch text files.
    watcher.Filter = "*.txt";

    // Add event handlers.
    watcher.Changed += new FileSystemEventHandler(OnChanged);
    watcher.Created += new FileSystemEventHandler(OnChanged);
    watcher.Deleted += new FileSystemEventHandler(OnChanged);
    watcher.Renamed += new RenamedEventHandler(OnRenamed);

    // Begin watching.
    watcher.EnableRaisingEvents = true;
}

// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
    // Specify what is done when a file is changed, created, or deleted.
   Console.WriteLine("File: " +  e.FullPath + " " + e.ChangeType);
}

private static void OnRenamed(object source, RenamedEventArgs e)
{
    // Specify what is done when a file is renamed.
    Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
}
Dirk Vollmar
fonte
11
Obrigado pelo bom exemplo. Também ressaltarei que você pode usar o método WaitForChanged em FileSystemWatcher se estiver procurando uma forma de bloqueio (síncrona) para observar as alterações.
Mark Meuer de
22
Obrigado por este exemplo. O MSDN tem praticamente o mesmo aqui . Além disso, algumas pessoas podem querer observar uma árvore de diretório inteira - use watcher.IncludeSubdirectories = true;para fazer isso.
Oliver
1
OnChangedispara sem mudança real ( por exemplo: rebatidas ctrl+ssem nenhuma mudança real ), há alguma maneira de detectar mudanças falsas?
Mehdi Dehghani
1
@MehdiDehghani: Não que eu saiba, a única maneira parece ser realmente manter um instantâneo do arquivo e comparar esse byte com a versão atual (provavelmente alterada). O FileSystemWatcherúnico é capaz de detectar eventos no nível do sistema de arquivos (ou seja, se o sistema operacional aciona um evento). No seu caso, Ctrl + S aciona tal evento (embora isso aconteça ou não, depende do aplicativo real).
Dirk Vollmar
O FileSystemWatcher é multiplataforma?
Vinigas
5

Use o FileSystemWatcher. Você pode filtrar apenas por eventos de modificação.

Shea
fonte