10 Stimmen

Gibt es eine Entsprechung zum .Net FileSystemWatcher in der Linux-Welt?

Ich finde die .Net FileSystemWatcher-Klasse sehr praktisch, um Dienstprogramme zu schreiben, die automatisch zum Leben erweckt werden, wenn Dateien in ihren überwachten Ordnern auftauchen. Gibt es ein Äquivalent zu dieser Funktionalität in der *nix-Welt, das es mir ermöglicht, einen Ordner (und möglicherweise alle seine Unterverzeichnisse) zu überwachen?

Bearbeiten: Vorzugsweise wird dies etwas sein, das keine Kernel-Patches erfordert.

15voto

J Mills Punkte 1720

Ich möchte meine Beobachtungen mit FileSystemWatcher in Mono in Ubuntu 10.10 teilen. Hier ist eine sehr einfache Implementierung von FileSystemWatcher in 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);
        }
    }
}

Dieser Code wurde getestet und funktioniert sowohl unter Windows XP als auch unter Ubuntu 10.10. Ich möchte jedoch darauf hinweisen, dass sich der FileSystemWatcher unter Ubuntu 10.10 (möglicherweise auch unter früheren Versionen) anders verhält.
Wenn das zu überwachende Verzeichnis keine Unterverzeichnisse enthält, führt der Aufruf eines FileSystemWatcher mit der Eigenschaft IncludeSubdirectories auf true dazu, dass der FileSystemWatcher Ereignisse ignoriert. Wenn jedoch Unterverzeichnisse im Zielverzeichnis vorhanden sind, funktioniert IncludeSubdirectories mit true wie erwartet.
Es wird immer funktionieren, wenn IncludeSubdirectories auf false gesetzt ist. In diesem Fall wird der FileSystemWatcher nur das Zielverzeichnis überwachen.
Ich hoffe, dies ist nützlich für Programmierer, die Mono über verschiedene Betriebssysteme hinweg nutzen und den FileSystemWatcher-Typ aufrufen möchten.

14voto

Mihai Limbășan Punkte 59901

Das wäre Gamin den Dateiveränderungsmonitor o Inotify .

Edit: Mono hat Gamin-Bindungen - in der Tat benutzt die Implementierung von FileSystemWatcher Gamin. https://www.mono-project.com/docs/faq/technical/#what-are-the-issues-with-filesystemwatcher .

Was sind die Probleme mit FileSystemWatcher?

Die Mono-Implementierung von FileSystemWatcher hat eine Reihe von Backends, das optimalste, das mit weniger Abhängigkeiten ist das inotify-Backend (verfügbar in Mono 1.1.17 und neueren Versionen).

Mit diesem Backend versorgt der Kernel Mono mit Updates bei Änderungen an Dateien im Dateisystem, aber es erfordert einen inotify-fähigen Kernel, der nur in neueren Linux-Distributionen enthalten ist.

Auf älteren Linux-Systemen müssen Sie FAM oder Gamin installiert haben (es funktioniert mit beiden). Möglicherweise müssen die -devel-Pakete installiert sein.

Für die *BSD-Familie gibt es eine Kqueue-basierte Implementierung, die verwendet wird, wenn sie zur Laufzeit erkannt wird.

Wenn keine der oben genannten Möglichkeiten funktioniert, greift Mono auf die Abfrage der Verzeichnisse nach Änderungen zurück, was alles andere als optimal ist.

6voto

Jordij Punkte 160

Wie bereits erwähnt, gibt es in Mono die Klasse "System.IO.FileSystemWatcher", dies ist der entsprechende Link: http://www.go-mono.com/docs/monodoc.ashx?link=T%3aSystem.IO.FileSystemWatcher

"Die Mono-Implementierung des FileSystemWatcher hat mehrere Backends. Dies ist notwendig, weil nicht alle Betriebssysteme, die von Mono unterstützten Betriebssysteme alle notwendigen Features haben um die von Anwendungen erwartete Funktionalität Anwendungen zu bieten.

Wenn der Kernel des Betriebssystems die Überwachung von Verzeichnissen unterstützt (inotify unter Linux, KEvents unter BSD oder OSX), wird diese Funktion verwendet; andernfalls fällt es zurück auf die Verwendung der Gamin- oder FAM Bibliotheken zurück (diese Bibliotheken bieten eine API zur Überwachung von Verzeichnissen) und wenn keine dieser Funktionen verfügbar ist, fragt Mono alle 750 Millisekunden die überwachten Verzeichnisse ab.

Sie können das Abfrageverhalten erzwingen erzwingen (anstatt die Kernelunterstützung zu nutzen) durch das Setzen der MONO_MANAGED_WATCHER Umgebungsvariable vor dem Ausführen Ihrer Anwendung setzen. Dies könnte nützlich sein für Dateisysteme, die keine Unterstützung für inotify nicht unterstützen und trotzdem ein Polling benötigen, um Änderungen zu erkennen."

2voto

Barry Kelly Punkte 40566

Ja, dnotify und inotify .

Ich weiß nicht, ob Mono diese verpackt hat, aber es wäre eine Überprüfung wert.

2voto

Wenn Sie die wunderbare QT-Bibliothek (www.qtsoftware.com) verwenden, ist sie als QFileSystemWatcher enthalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X