Подтвердить что ты не робот

Уведомление об изменении файловой системы на уровне файлов в Mac OS X

Я хочу, чтобы мой код был уведомлен, когда какой-либо файл (прямо или косвенно) изменен в заданном каталоге. Под "измененным" я имею в виду, что я хочу, чтобы мой код был уведомлен при изменении содержимого файла, его переименовании или удалении; или если добавлен новый файл. Для моего приложения могут быть тысячи файлов.

Я смотрел как FSEvents, но его Обзор технологий говорит, в частности:

Важным моментом для удаления является то, что степень детализации уведомлений находится на уровне каталога. Это говорит вам только о том, что что-то в каталоге изменилось, но не сообщает вам, что изменилось.

В нем также говорится:

API событий файловой системы также не предназначен для определения того, когда изменяется конкретный файл. Для этих целей механизм kqueues более уместен.

Однако, чтобы использовать kqueue в данном файле, нужно открыть файл, чтобы получить файловый дескриптор. Нецелесообразно управлять тысячами дескрипторов файлов (и, возможно, превысит максимально допустимое количество дескрипторов открытых файлов).

Любопытно, что в Windows я могу использовать функцию ReadDirectoryChangesW(), и она делает именно то, что я хочу.

Итак, как можно делать то, что я хочу в Mac OS X? Или, задал другой вопрос: как можно написать эквивалент ReadDirectoryChangesW() для Mac OS X в пользовательском пространстве (и сделать это очень эффективно)?

4b9b3361

Ответ 1

Я не пробовал это сам, но кажется, что FSEvents может предоставлять уведомления на уровне файлов с 10.7 (Lion). Из описание FSEventStreamCreateFlags:

kFSEventStreamCreateFlagFileEvents

Запросить уведомления на уровне файлов. Ваш поток будет получать события о отдельных файлах в иерархии, которую вы смотрите, а не только получать уведомления на уровне каталогов. Используйте этот флаг с осторожностью, поскольку он будет генерировать значительно больше событий, чем без него.

Доступно в OS X v10.7 и более поздних версиях.

Ответ 2

EDIT: Не проверено, но Константин указывает ниже, что этот образец кода устарел с 2012 года.

Я не верю, что есть конкретный API для того, что вы ищете. Apple предоставляет пример кода для аналогичной проблемы, называемой Watcher. Это не то, что вы ищете, но это самое лучшее, что вы можете сделать в этот момент. Вам нужно сделать снимки каталога и повторно просмотреть его, когда вы узнаете, что что-то изменилось. Конечно, время модификации - это лучшее, что можно проверить, если вы можете доверять времени модификации.

Вероятно, вы правы, что попытка зарегистрироваться для неограниченного количества kqueues, вероятно, будет неработоспособной.

Ответ 3

Ближайшая утилита (которая я знаю), которая соответствует вашим потребностям в Mac OS X, составляет fslogger. См. Ссылку для описания, dmg и исходный код: OSXBook - fslogger

Ответ 4

Возможно, вы захотите проверить man fs_usage, хотя он не определен для каталога и требует привилегий root.