FSEvents - 找出目标目录中的更改内容

时间:2013-01-17 09:56:04

标签: objective-c fsevents

我只是设置FSEvent以监控目标文件夹的状态。它工作得很好,因为每次发生更改时我都会收到通知,并且还会给出发生更改的子目录的路径。 但是,如果我想要进行什么操作呢?文件是否已添加,修改,重命名或删除?

在Mac Developer Library中,我正在阅读使用持久性事件

  

“即使应用程序未运行,您也可以找到已修改的文件。这可以大大简化诸如备份已修改文件,检查多文件项目中更改的依赖项等任务。”

但如果我理解得很好,这只是一种比较目录的当前状态与事件ID定义的前一状态的方法。所以我再次只能获得发生更改的子目录的路径。

我的问题是:我是否真的必须通过创建Directory Hierarchy Snapshots在不同时间“手动”拍摄我的目录状态的快照,然后比较它们以便找出当时执行的操作快照之间?是不是有更快的方式?

1 个答案:

答案 0 :(得分:3)

我做了以下操作,以便能够区分使用FSEvent(文件已添加,文件已重命名,文件已删除和文件已修改)正在监视的文件夹内的文件的不同操作。

我创建了一个具有以下属性的对象File(通过调用attributesOfItemAtPath:error:可以获得任意数量的对象):

@property (strong) NSString *name;
@property (strong) NSString *type;
@property (strong) NSDate *creationDate;
@property (strong) NSDate *modificationDate;
@property (strong) NSString *hash;
@property (strong) NSString *path;

可以通过以下方式填充NSMutableArray个File对象:

NSMutableArray *files = [[NSMutableArray alloc] init];
NSString *dirPath = //directory you are watching
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *theFiles =  [fileManager contentsOfDirectoryAtURL:[NSURL fileURLWithPath:dirPath]
                                includingPropertiesForKeys:[NSArray arrayWithObject:NSURLNameKey]
                                                   options:NSDirectoryEnumerationSkipsHiddenFiles
                                                     error:nil];
NSArray* fileNames = [theFiles valueForKeyPath:@"lastPathComponent"];
if ( [fileNames count] > 0 ) {
    for (NSInteger i=0; i<[fileNames count]; i=i+1) {
        NSString *currentPath = [dirPath stringByAppendingString:[fileNames objectAtIndex:i]];
        NSError *error;
        NSDictionary *fileInfo = [fileManager attributesOfItemAtPath:currentPath error:&error];
        File *currentFile = [[File alloc] initWithName:[fileNames objectAtIndex:i]
                                                  withType:fileInfo.fileType
                                                  withPath:currentPath
                                                  withHash: //get file hash
                                          withCreationDate:fileInfo.fileCreationDate
                                   andWithModificationDate:fileInfo.fileModificationDate];
        [files addObject:currentFile];
}

如果目录包含子文件夹,则为每个子文件夹,返回和File对象数组迭代此过程就足够了。

要了解执行了哪些操作,现在就足以面对之前收集的信息(保存在NSMutableArray *oldSnap中)以及NSMutableArray *newSnap的回调后(保存在FSEvent中)。首先,有必要将oldSnap中的文件与newSnap中的文件对峙,然后反之。

如果在oldSnapnewSnap中缺少具有给定名称的文件,则表示此文件已被删除或重命名。如果文件在newSnap中具有相同的哈希值,则该文件已重命名;否则它已从文件夹中删除。

通过比较完成,如果newSnap中的文件与fileModificationDate中具有相同名称的文件不同oldSnap,则此文件已被修改。如果oldSnap中缺少newSnap中的文件,则此文件是新添加的文件。

我还没有提出一个重命名和修改文件的解决方案。希望这个答案可以帮助别人!