私は mac os x で Kqueues を使用していて、フォルダーを監視しようとしているので、EVFILT_VNODE フィルターを使用しました。ファイルが削除されるたびに通知を受け取りたいのですが、NOTE_DELETE
ファイルが削除されたときにのみ検出しますがunlink() system call
、ファイルをゴミ箱に移動するときではありません。
問題は、ファイルがゴミ箱に移動されたことをどのように検出できますか?
これを行う簡単な方法はありません。kqueue()
ファイルが移動された(名前が変更された)ときに通知できますが、ごみ箱が特別な宛先であるとは見なされず、ファイルの継続的な存在に関して特別な意味があるとは見なされません。つまり、ファイルをごみ箱に移動することは、BSD レイヤーに関する限り、ファイルを他のディレクトリに移動することと同じです。
NOTE_RENAME
そのため、ファイルがいつ移動/名前変更されたかを監視します。次に、 を使用fcntl(fd, F_GETPATH, buffer)
して新しいパスを見つけることができます。ハードリンクされたファイルの場合、これは、ユーザーが考えるアイテムのパスではなく、他のリンクのいずれかへのパスを提供する場合があることに注意してください。ただし、これはかなりまれなはずです。
次に、新しいパスがゴミ箱内にあるかどうかを確認する必要があります。それも複雑です。
OS X 10.10 以降が必要な場合は、[[NSFileManager defaultManager] getRelationship:&relationship ofDirectory:NSTrashDirectory inDomain:0 toItemAtURL:[NSURL fileURLWithPath:pathFromFcntl] error:NULL]
. そのメソッドが true を返し、relationship
以外に設定されている場合NSURLRelationshipOther
、ファイルはゴミ箱に移動されています。
バージョン 10.9 以前をサポートする必要がある場合は、手動で行う必要があります。
ゴミ箱ディレクトリは 1 つだけではありません。各ボリュームには、ユーザーごとに異なるディレクトリがあります。特定のファイルが使用するごみ箱ディレクトリを見つけるには、 を呼び出します[[NSFileManager defaultManager] URLForDirectory:NSTrashDirectory inDomain:NSUserDomainMask appropriateForURL:[NSURL fileURLWithPath:pathFromFcntl] create:NO error:NULL]
。
次に、新しいパスがそのディレクトリ内のどこかにあるかどうかを判断する必要があります (ディレクトリのすぐ内側だけではありません)。パスのディレクトリを反復する必要があります。ディレクトリごとに、-[NSURL getResourceValue:forKey:error:]
withNSURLFileResourceIdentifierKey
をキーとして使用してリソース識別子を取得します。ごみ箱ディレクトリに同じ値を取得します。を使用して 2 つを比較し-isEqual:
ます。リソース識別子がごみ箱ディレクトリのものと同じ祖先ディレクトリが見つかった場合、そのファイルはごみ箱にあります。祖先ディレクトリの反復がそれを見つけずにルートに到達した場合、そうではありません。