2009-11-20 4 views
26

Ich möchte mein Code benachrichtigt werden, wenn eine Datei unter (entweder direkt oder indirekt) ein bestimmtes Verzeichnis geändert wird. Mit "geändert" meine ich, dass mein Code benachrichtigt werden soll, wenn der Inhalt einer Datei geändert, umbenannt oder gelöscht wird. oder wenn eine neue Datei hinzugefügt wird. Für meine Anwendung kann es Tausende von Dateien geben.Datei-Level-Dateisystem ändern Benachrichtigung in Mac OS X

Ich sah aus, als FSEvents, aber seine Technologie Übersicht sagt unter anderem:

Der wichtige Punkt ist wegzunehmen, dass die Granularität der Meldungen in einem Verzeichnisebene ist. Es sagt Ihnen nur, dass sich etwas im Verzeichnis geändert hat, sagt Ihnen aber nicht, was sich geändert hat.

Er sagt auch:

Die API-Dateisystemereignisse ist auch nicht dafür ausgelegt, um herauszufinden, wenn eine bestimmte Datei ändert. Für solche Zwecke ist der Kqueues-Mechanismus geeigneter.

Um jedoch kqueue für eine bestimmte Datei zu verwenden, muss man die Datei öffnen, um einen Dateideskriptor zu erhalten. Es ist unpraktisch, Tausende von Dateideskriptoren zu verwalten (und würde wahrscheinlich sowieso die maximal zulässige Anzahl von offenen Dateideskriptoren überschreiten).

Kurioserweise kann ich unter Windows die ReadDirectoryChangesW() Funktion verwenden und es tut genau was ich will.

Also wie kann man unter Mac OS X machen, was ich will? Oder anders gefragt: Wie würde man das Äquivalent von ReadDirectoryChangesW() für Mac OS X im User-Space schreiben (und das sehr effizient)?

Antwort

6

ich das selbst noch nicht ausprobiert, aber es scheint, wie FSEvents in der Lage, Dateiebene Meldungen ab 10.7 (Lion) zur Verfügung zu stellen. Von the description of FSEventStreamCreateFlags:

kFSEventStreamCreateFlagFileEvents

Antrag auf Dateiebene Benachrichtigungen. Ihr Stream empfängt Ereignisse zu einzelnen Dateien in der angezeigten Hierarchie, anstatt nur Benachrichtigungen auf Verzeichnisebene zu empfangen.Verwenden Sie dieses Flag mit Bedacht, da es wesentlich mehr Ereignisse generiert als ohne es.

Verfügbar in OS X v10.7 und höher.

8

EDIT: nicht überprüft, aber Konstantin unten zeigt, dass dieses Codebeispiel ist veraltet ab 2012

Ich glaube nicht, gibt es eine bestimmte API für das, was Sie suchen. Apple bietet Beispielcode für ein ähnliches Problem mit der Bezeichnung Watcher. Es ist nicht das, was Sie suchen, aber es ist das Beste, was Sie an diesem Punkt tun können. Sie müssen Snapshots des Verzeichnisses erstellen und es erneut scannen, wenn Sie feststellen, dass sich etwas geändert hat. Modifikationszeit ist natürlich die beste Sache, wenn Sie Modifikationszeit vertrauen können.

Sie haben wahrscheinlich Recht, dass der Versuch, sich für eine unbegrenzte Anzahl von kqueues zu registrieren, wahrscheinlich nicht funktioniert.

+0

Ich mag generell keine Windows-Programmierung und bevorzuge Mac/Linux-Programmierung. Es scheint einfach bizarr, dass es anscheinend mindestens eine Sache gibt, die in Windows einfacher ist. –

+3

Oh, unter Windows sind viele Dinge einfacher zu machen. Sprechen Sie SOAP mit Cocoa. NSArray ist nett, aber manchmal wäre ein C# -Stil generic sehr willkommen. Mac hat nichts mit ASP.NET zu tun (Ich schaue dich an, WebObjects). Ich liebe Kakao; Es ist bei weitem der beste Rahmen, den ich jemals erlebt habe. Aber jeder, der denkt, dass alles besser für Entwickler auf Mac als Windows ist, hat sich auf beiden Seiten nicht sehr entwickelt. Für solche Sachen warten wir alle auf diesen heiligen Gral von ZFs, der diese Art von Dingen einfacher und schneller machen könnte. Eines Tages ... (Microsoft hat seine Träume von Winfs auch ...) –

+1

Das Problem ist, dass Sie Linux-Programmierung mit Mac-Programmierung bündeln. Unter inotifywait ist dies sehr einfach unter Linux möglich. – MarkovCh1

-2

Sie möchten vielleicht man fs_usage auschecken, obwohl es nicht für ein Verzeichnis spezifisch ist und Root-Rechte erfordert.

2

Das nächste Dienstprogramm (das ich kenne), das Ihren Anforderungen auf Mac OS X entspricht, ist fslogger. Siehe den Link für eine Beschreibung, dmg und Quellcode: OSXBook - fslogger