3

我只是设置了一个FSEvent以监视目标文件夹的状态。它工作得很好,因为每次发生更改时都会通知我,并且我还会获得发生更改的子目录的路径。但是,如果我想了解执行的操作是什么?是否添加、修改、重命名或删除了文件?

在 Mac 开发人员库中,我通过使用持久事件来阅读

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

但如果我理解得很好,这只是将目录的当前状态与事件 ID 定义的前一个状态进行比较的一种方式。因此,我只会获得发生更改的子目录的路径。

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

4

1 回答 1

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;

可以通过以下方式填充NSMutableArrayFile 对象:

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 *oldSnapNSMutableArray *newSnap. FSEvent首先,有必要将文件与文件放在oldSnap一起newSnap,然后反之亦然。

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

完成比较,如果 中的文件与 中的同名文件newSnap不同,则该文件已被修改。如果 newSnap 中有一个文件在fileModificationDateoldSnapoldSnap,则该文件是新添加的。

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

于 2013-01-18T21:55:15.780 回答