Остановка файлового монитора после сохранения файла - PullRequest
0 голосов
/ 17 августа 2011

Я пытаюсь отслеживать издание одного файла, используя kqueue через упаковку UKKQueue, доступную здесь . Эта оболочка очень проста, вот код теста, который я использую:

@implementation FileMonitorTestAppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    fileWatcher = [[UKKQueue alloc] init];
    [fileWatcher addPath:@"/Users/bruno/Desktop/SyncTestLog"];
    [fileWatcher setDelegate:self];
}

- (void)dealloc {
    [fileWatcher release];
}

-(void) watcher: (id<UKFileWatcher>)kq receivedNotification: (NSString*)nm forPath: (NSString*)fpath {
    NSLog(@"UKFileWatcher: %@ - notification: %@ - filePath: %@", kq, nm, fpath);
}

@end

Файл в /Users/bruno/Desktop/SyncTestLog является простым текстовым файлом. Когда я редактирую его, используя nano от терминала, вывод показывает, как ожидалось:

2011-08-17 11:46:27.316 FileMonitorTest[1235:707] UKFileWatcher: <UKKQueue: 0x100117da0> - notification: UKKQueueFileWrittenToNotification - filePath: /Users/bruno/Desktop/SyncTestLog
2011-08-17 11:46:27.317 FileMonitorTest[1235:707] UKFileWatcher: <UKKQueue: 0x100117da0> - notification: UKKQueueFileSizeIncreasedNotification - filePath: /Users/bruno/Desktop/SyncTestLog
2011-08-17 11:46:27.751 FileMonitorTest[1235:707] UKFileWatcher: <UKKQueue: 0x100117da0> - notification: UKKQueueFileAttributesChangedNotification - filePath: /Users/bruno/Desktop/SyncTestLog

Теперь, когда я редактирую его с помощью TextEdit или TextWrangler, мониторинг прекращает сообщать об изменениях после первого сохранения файла. Вот последние события, о которых сообщают:

2011-08-17 10:57:45.792 FileMonitorTest[897:707] UKFileWatcher: <UKKQueue: 0x10035ae10> - notification: UKKQueueFileAttributesChangedNotification - filePath: /Users/bruno/Desktop/SyncTestLog
2011-08-17 10:57:46.463 FileMonitorTest[897:707] UKFileWatcher: <UKKQueue: 0x10035ae10> - notification: UKKQueueFileAttributesChangedNotification - filePath: /Users/bruno/Desktop/SyncTestLog
2011-08-17 10:57:54.043 FileMonitorTest[897:707] UKFileWatcher: <UKKQueue: 0x10035ae10> - notification: UKKQueueFileDeletedNotification - filePath: /Users/bruno/Desktop/SyncTestLog

Насколько я понимаю, UKKQueue получает дескриптор файла в стиле unix с open () с использованием флага O_EVTONLY. По какой-то причине TextEdit (и TextWrangler) генерируют это UKKQueueFileDeletedNotification уведомление при сохранении файла.

Что мне нужно, так это продолжать слушать изменения в файле "навсегда". Я полагаю, что смогу заново создать монитор, когда появится UKKQueueFileDeletedNotification, но я ищу что-нибудь более чистое.

Спасибо

Edit: Я только что нашел в Google Toolbox для Mac класс с именем GTMFileSystemKQueue , который решает мою проблему. На мой вопрос все еще нет ответа.

Ответы [ 2 ]

3 голосов
/ 30 марта 2012

Я переписал UKKQueue в современном Objective-C.Новый класс работает так же, он просто лучше, быстрее и оптимизирован.Также исправлена ​​ошибка, описанная в этом посте, наряду с несколькими другими.

Новый класс VDKQueue можно найти здесь: http://github.com/bdkjones/VDKQueue

1 голос
/ 23 октября 2012

Суть в том, что TextEdit и TextWrangler используют безопасное сохранение (или ...atomically:YES), которое записывает не прямо в файл, а сначала записывает во временный файл, затем переименовывает файлы, чтобы заменить исходный путь файломсохранено во временном местоположении.

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

GTMFileSystemKQueue работает из-за параметра acrossReplace, который отслеживает операции удаления / переименования и перерегистрирует kqueue по исходному пути.Быстрая проверка UKKQueue и VDKQueue, по-видимому, показывает, что ни один из них не делает этого.

...