web-dev-qa-db-ja.com

Mac OSXでのファイルレベルのファイルシステム変更通知

特定のディレクトリの下にあるファイルが(直接的または間接的に)変更されたときにコードに通知する必要があります。 「変更された」とは、ファイルの内容が変更されたり、名前が変更されたり、削除されたりしたときにコードに通知することを意味します。または、新しいファイルが追加された場合。私のアプリケーションでは、何千ものファイルが存在する可能性があります。

私はFSEventsのように見えましたが、そのテクノロジーの概要には、部分的に次のように書かれています。

重要なポイントは、通知の粒度がディレクトリレベルにあることです。ディレクトリ内の何かが変更されたことだけを通知しますが、何が変更されたかは通知しません。

それはまた言う:

ファイルシステムイベントAPIも、特定のファイルがいつ変更されたかを検出するようには設計されていません。このような目的には、kqueuesメカニズムがより適切です。

ただし、特定のファイルでkqueueを使用するには、ファイルを開いてファイル記述子を取得する必要があります。何千ものファイル記述子を管理することは実用的ではありません(とにかく、開いているファイル記述子の最大許容数を超える可能性があります)。

不思議なことに、Windowsでは、ReadDirectoryChangesW()関数を使用でき、それは私が望むことを正確に実行します。

では、Mac OS Xで私がやりたいことをどのように行うことができますか?または、別の方法で質問しました。MacOSX用のReadDirectoryChangesW()に相当するものをユーザースペースに書き込むにはどうすればよいでしょうか(非常に効率的に記述できます)。

27
Paul J. Lucas

私自身はこれを試していませんが、FSEventsは10.7(Lion)の時点でファイルレベルの通知を提供できるようです。 From FSEventStreamCreateFlagsの説明

kFSEventStreamCreateFlagFileEvents

ファイルレベルの通知を要求します。ストリームは、ディレクトリレベルの通知だけを受信するのではなく、監視している階層内の個々のファイルに関するイベントを受信します。このフラグは、フラグがない場合よりもはるかに多くのイベントを生成するため、注意して使用してください。

OS Xv10.7以降で利用できます。

6
legoscia

編集:検証されていませんが、Konstantinは、このコードサンプルが2012年の時点で廃止されていることを以下に示しています。

あなたが探しているものに特定のAPIがあるとは思いません。 Appleは Watcher と呼ばれる同様の問題のサンプルコードを提供します。これはあなたが探しているものではありませんが、現時点でできる最善のことです。あなたディレクトリのスナップショットを作成し、何か変更があった場合は再スキャンする必要があります。変更時間を信頼できる場合は、もちろん変更時間を確認するのが最善です。

無制限の数のkqueueに登録しようとすると、実行できない可能性が高いというのはおそらく正しいでしょう。

8
Rob Napier

Mac OS Xでのニーズに一致する(私が知っている)最も近いユーティリティはfsloggerです。説明、dmg、およびソースコードについては、リンクを参照してください: OSXBook --fslogger

2
Honcho