2008-11-27 6 views
8

Je trouve la classe .Net FileSystemWatcher très pratique pour écrire des utilitaires qui prennent automatiquement vie lorsque des fichiers apparaissent dans leurs dossiers surveillés. Y a-t-il un équivalent de cette fonctionnalité dans le monde * nix qui me permettrait de regarder un dossier (et éventuellement tous ses sous-répertoires)?Y at-il un équivalent à .Net FileSystemWatcher dans le monde Linux?

Édition: De préférence, cela ne nécessitera pas de correctifs de noyau.

Répondre

2

Oui, dnotify et inotify.

Je ne sais pas si Mono a ces enveloppés, mais ça vaut le coup de vérifier.

+0

J'ai lu ailleurs que le FileSystemWatcher ne fonctionne pas avec les systèmes de fichiers de Linux lors de l'exécution dans un environnement Mono. Merci quand même. – Luke

+0

Le problème avec inotify est qu'il n'est pas portable b/c il n'existe que sous linux et pas sous Unix en général. –

+0

Beagle utilise inotify, donc c'est définitivement emballé dans Mono quelque part. –

6

Comme on l'a déjà dit, Mono a la classe « System.IO.FileSystemWatcher », c'est le lien correspondant. http://www.go-mono.com/docs/monodoc.ashx?link=T%3aSystem.IO.FileSystemWatcher

« la mise en œuvre du Mono FileSystemWatcher a plusieurs backends Ceci est nécessaire parce que tous les systèmes d'exploitation pris en charge par Mono ont toutes les caractéristiques nécessaires pour fournir la fonctionnalité attendue par les applications.

Si le noyau du système d'exploitation prend en charge le suivi des répertoires (inotify sous Linux, KEvents sur BSD ou OSX) que la fonctionnalité est utilisée; Sinon, il tombe retour à l'aide de la FAM ou Gamin bibliothèques (ces bibliothèques fournissent une API pour surveiller les répertoires) et si aucune de ces fonctionnalités sont disponibles, Mono Interroger toutes les 750 millisecondes les répertoires surveillés.

Vous pouvez forcer le comportement de vote (au lieu d'utiliser le support du noyau) en définissant la variable d'environnement MONO_MANAGED_WATCHER avant d'exécuter votre application. Cela peut être utile pour les systèmes de fichiers qui ne prennent pas en charge inotify et encore requièrent une interrogation pour détecter les changements. »

2

Si vous utilisez la bibliothèque QT merveilleux (www.qtsoftware.com) il est inclus dans le QFileSystemWatcher .

13

Salutations, Je voudrais partager mes observations à l'aide FileSystemWatcher Mono dans Ubuntu 10.10. Voici une implémentation très simple de FileSystemWatcher en C#

using System; 
using System.Collections.Generic; 
using System.Collections; 
using System.Text; 
using System.IO; 
using System.Reflection; 

namespace FileSystemWatcherSandbox 
{ 
    public class Program 
    { 
     static void Main(string[] args) 
     { 
      foreach(DictionaryEntry de in Environment.GetEnvironmentVariables()) 
      { 
       Console.WriteLine("{0} = {1}",de.Key,de.Value); 
      } 
      string basePath = AppDomain.CurrentDomain.BaseDirectory; 
      Console.WriteLine("watching: {0}", basePath); 
      FileSystemWatcher fsw = new FileSystemWatcher(basePath); 
      fsw.Changed += new FileSystemEventHandler(fsw_Changed); 
      fsw.Created += new FileSystemEventHandler(fsw_Created); 
      fsw.Deleted += new FileSystemEventHandler(fsw_Deleted); 
      fsw.Error += new ErrorEventHandler(fsw_Error); 
      fsw.Renamed += new RenamedEventHandler(fsw_Renamed); 
      fsw.EnableRaisingEvents = true; 
      fsw.IncludeSubdirectories = true; 
      while (true) 
      { 
       WaitForChangedResult result = fsw.WaitForChanged(WatcherChangeTypes.All,10000); 
       Console.WriteLine(result.TimedOut ? "Time out" : "hmmm"); 
      } 
     } 

     static void fsw_Renamed(object sender, RenamedEventArgs e) 
     { 
      Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath); 
     } 

     static void fsw_Error(object sender, ErrorEventArgs e) 
     { 
      Console.WriteLine("({0}): {1}", MethodInfo.GetCurrentMethod().Name, e.GetException().Message); 
     } 

     static void fsw_Deleted(object sender, FileSystemEventArgs e) 
     { 
      Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath); 
     } 

     static void fsw_Created(object sender, FileSystemEventArgs e) 
     { 
      Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath); 
     } 

     static void fsw_Changed(object sender, FileSystemEventArgs e) 
     { 
      Console.WriteLine("({0}): {1} | {2}", MethodInfo.GetCurrentMethod().Name, e.ChangeType, e.FullPath); 
     } 
    } 
} 

Ce code a été testé et fonctionne à la fois sur Windows XP et Ubuntu 10.10. Cependant, je voudrais souligner que sous Ubuntu 10.10 (peut-être aussi des versions antérieures), le FileSystemWatcher se comporte de manière unique.
Si le répertoire en cours de surveillance ne contient pas de sous-répertoires, l'appel d'un FileSystemWatcher avec la propriété IncludeSubdirectories définie sur true entraîne l'ignorance des événements FileSystemWatcher. Toutefois, s'il existe des sous-répertoires dans le répertoire cible, alors IncludeSubdirectories défini sur true fonctionnera comme prévu.
Ce qui fonctionnera toujours est si IncludeSubdirectories a la valeur false. Dans ce cas, FileSystemWatcher ne surveillera que le répertoire cible.
J'espère que cela est utile pour les programmeurs qui souhaitent utiliser Mono sur différents systèmes d'exploitation et appeler le type FileSystemWatcher.

chickenSandwich