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

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

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

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

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

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

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

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

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


person Paul J. Lucas    schedule 20.11.2009    source источник


Ответы (4)


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

kFSEventStreamCreateFlagFileEvents

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

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

person legoscia    schedule 27.05.2014

РЕДАКТИРОВАТЬ: не проверено, но Константин указывает ниже, что этот образец кода устарел с 2012 года.

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

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

person Rob Napier    schedule 23.11.2009
comment
Обычно я не люблю программирование для Windows и предпочитаю программирование для Mac/Linux. Просто кажется странным, что есть по крайней мере 1 вещь, которую проще сделать в Windows. - person Paul J. Lucas; 24.11.2009
comment
О, есть много вещей, которые проще сделать в Windows. Попробуйте говорить SOAP, используя Cocoa. NSArray — это хорошо, но иногда дженерик в стиле C# будет очень кстати. У Mac нет ничего даже близкого к ASP.NET (я смотрю на вас, WebObjects). Я люблю какао; это, безусловно, лучший фреймворк, с которым я когда-либо сталкивался. Но любой, кто думает, что для разработчиков на Mac все лучше, чем на Windows, не особо развился на обоих. Для таких вещей мы все ждем этого святого Грааля zfs, который может сделать такие вещи проще и быстрее. Когда-нибудь... (Microsoft тоже мечтает о winfs...) - person Rob Napier; 24.11.2009
comment
Проблема в том, что вы объединяете программирование для Linux с программированием для Mac. Это очень легко сделать в Linux с помощью inotifywait. - person MarkovCh1; 10.08.2012

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

person ideasuns    schedule 02.09.2011

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

person JWWalker    schedule 15.06.2010