如何在Cocoa中获取文件夹变更通知(文件夹监视器)

3
我是Cocoa应用程序开发的新手。我希望当给定目录下的任何文件被修改时(文件夹监视器),我的应用程序能够收到通知。修改意味着删除、添加或更改文件内容。我尝试使用FSEvents,同时使用NSWorkspace的通知中心或委托消息,如UKKQueue中所述。在http://www.zathras.de/angelweb/sourcecode.htm#UKKQueue上,我的应用程序可以在目录下的任何文件被修改时收到通知。但问题是它没有提供被修改的特定文件的名称或路径。它只提供了目录的路径,而不是特定文件的路径。
有什么办法可以监视特定文件的文件夹修改吗?

可能是在Objective-C中观察文件或文件夹的重复问题。 - Rob Keniger
kqueues将监视单个文件的更改,但您必须自己设置每个文件的监视。 UKKQueue开箱即用时并不太适用于此,因为它只允许单个委托。 - Rob Keniger
有没有其他方法可以根据我的需求监视文件夹? - Amrinder Singh
2个回答

7
您需要编写代码来跟踪文件夹的内容,每当收到FSEvent通知文件夹内容已更改时,您需要将存储的文件夹内容信息与实际当前内容进行比较。
这可以是一个简单的可变数组ivar,命名为folderContents,其中包含一组文件属性字典。您可以使用从NSFileManager-attributesOfItemAtPath:error:方法返回的字典或其子集。
当您收到文件夹通知时,您只需要遍历存储的字典并检查是否添加,删除或修改了任何文件即可。 NSFileManager的属性字典包含执行此操作所需的所有信息。
然后,您需要使用更新后的信息更新有关文件夹的存储信息。

你能给我提供一个示例代码吗?因为我之前说过,我是Cocoa应用程序开发的新手。 - Amrinder Singh

5

NSMetadataQuery适用于监视文件夹:

- (void)setupWatchedFolder {
    NSString *watchedFolder = @"/path/to/foo";

    NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
    [query setSearchScopes:@[watchedFolder]];
    [query setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE '*.*'", NSMetadataItemFSNameKey]];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(queryFoundStuff:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
    [nc addObserver:self selector:@selector(queryFoundStuff:) name:NSMetadataQueryDidUpdateNotification object:query];

    [query startQuery];
}

- (void)queryFoundStuff:(NSNotification *)notification {

    NSMetadataQuery *query = self.metadataQuery;
    [query disableUpdates];

    NSMutableArray *results = [NSMutableArray arrayWithCapacity:self.metadataQuery.resultCount];

    for (NSUInteger i=0; i<self.metadataQuery.resultCount; i++) {
        [results addObject:[[self.metadataQuery resultAtIndex:i] valueForAttribute:NSMetadataItemPathKey]];
    }

    // do something with you search results
    // self.results = results;

    [query enableUpdates];
}

这个想法看起来不错,但我无法让它工作。QueryFoundStuff从未被调用过。 - Matthieu Riegler
@MatthieuRiegler 我已经更新了查询谓词以匹配我在应用程序中使用的内容。 - mrwalker
1
有没有可能使用NSMetadataQuery + NSNotificationCenter仅获取操作(文件重命名,文件移动,文件添加),而无需迭代整个监视文件夹并映射到上一个文件夹快照的完整路径名称? 我尝试实现一个DirectoryWatcher来通知其他代码部分,在监视的文件夹中删除、添加或重命名文件时。我想发送操作+文件路径。 你能给我一些提示吗?谢谢 - DoK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接