Être notifié lors d’un changement de contenue de fichier

Être notifié lors d’un changement de contenue de fichier

2018-10-22 0 By Sauleil

Il arrive souvent qu’on aille des fichiers de configuration pour nos application. Lorsqu’on fait fait une modification, on doit repartir l’application. Donc, le mieux serait d’avoir un mécanisme qui reload les configurations au “runtime“.

FileSystemWatcher

Il y  a déjà plusieurs articles de disponible sur cette classe. Donc je n’irai pas dans les détails. Le concept est assez simple: on donne un répertoire et on s’abonne aux évènements.

private void Init() {
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = "path/you/want/to/watch";
    watcher.Filter = "*.json"; // if you want to watch only 1 file, write the filename here
    watcher.EnableRaisingEvents = true; // Don't forget this, or else it won't start the watcher.

    watcher.Changed += new FileSystemEventHandler(OnChanged);
}

// Define the event handlers.
private 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);
}

Ça fonctionne bien généralement. Par contre, si vous voulez utiliser ça dans votre projet .Net, vous risquez d’avoir une mauvaise surprise. Pour une raison de sécurité des fichiers, Visual Studio crée un fichier temporaire si un fichier de votre projet est utilisé. Il devient donc impossible de “watcher” un fichier spécifique, comme le nom et l’extension seront perdu quand le “OnChanged” sera appelé.

Donc, il faut se tourner vers une méthode alternative.

System.Web.Caching

Si vous avez déjà fait du ASP.Net, il est for probable que vous ailliez déjà travailler avec le système de cache par défaut. Ce qui est bien avec cette cache, c’est qu’on peut associer un fichier avec sa valeur dedans. Voici un exemple simple:

public string AddItemToCache(string filename) {
    var content = File.ReadAllText(filename);
    Cache.Add("Key1", 
        content, 
        new CacheDependency(fileName), 
        DateTime.Now.AddSeconds(60), 
        Cache.NoSlidingExpiration, 
        CacheItemPriority.High);

    return content;
}

public string GetConfig() {
    var content = Cache.Get("Key1");
    if (content == null)
        content = AddItemToCache("file.config");

    content content;
}

Conclusion

J’ai écrit cet article parce que j’ai perdu beaucoup de temps pour rien avec le FileSystemWatcher pour réussir à comprendre la limitation. Donc, si vous avez d’autres alternatives, n’hésitez pas à m’en faire part, il me fera plaisir de l’ajouter à l’article.