gpt4 book ai didi

cocoa - 是否可以使用 FSEvents 获取文件夹已移动的通知?

转载 作者:行者123 更新时间:2023-12-03 16:06:33 26 4
gpt4 key购买 nike

我正在使用 FSEvents API 来获取我正在跟踪的本地目录中的更改通知。

是否可以使用 FSEvents 或其他任何方式获取监视目录已移动到磁盘上其他位置的通知?

更新:

这是我到目前为止的代码,我现在尝试将 kFSEventStreamCreateFlagWatchRoot 标志与 FSEventStreamCreate 一起使用来获取根更改通知,但到目前为止还没有成功。

- (void)registerForFileSystemNotifications {

NSString *watchedDirectoryPath = [[NSUserDefaults standardUserDefaults] valueForKey:kMyWatchedDirectoryPathKey];
self.watchedDirectoryFileDescriptor = open([watchedDirectoryPath cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY);

NSArray *paths = [NSArray arrayWithObject:watchedDirectoryPath];
void *appController = (void *)self;
FSEventStreamContext context = {0, appController, NULL, NULL, NULL};
FSEventStreamRef streamRef = FSEventStreamCreate(NULL,
&fsevents_callback,
&context,
(CFArrayRef) paths,
kFSEventStreamEventIdSinceNow,
(CFTimeInterval)2.0,
kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagWatchRoot);

FSEventStreamScheduleWithRunLoop(streamRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(streamRef);

}

void fsevents_callback(ConstFSEventStreamRef streamRef,
void *userData,
size_t numumberOfEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[]) {

MyAppController *appController = (MyAppController *)userData;
char *newPath = calloc(4096, sizeof(char));
int pathIntPointer = (int)newPath;

int length = fcntl(appController.watchedDirectoryFileDescriptor, F_GETPATH, pathIntPointer);

NSString *newPathString = [[NSString alloc] initWithBytes:newPath length:(NSUInteger)length encoding:NSUTF8StringEncoding];
NSLog(@"newPathString: %@", newPathString); // empty
}

最佳答案

是的。将 kFSEventStreamCreateFlagWatchRoot 作为最后一个参数传递给 FSEventStreamCreate,如果目录被移动或重命名,您将会收到通知。来自 docs :

Request notifications of changes along the path to the path(s) you're watching. For example, with this flag, if you watch "/foo/bar" and it is renamed to "/foo/bar.old", you would receive a RootChanged event. The same is true if the directory "/foo" were renamed. The event you receive is a special event: the path for the event is the original path you specified, the flag kFSEventStreamEventFlagRootChanged is set and event ID is zero. RootChanged events are useful to indicate that you should rescan a particular hierarchy because it changed completely (as opposed to the things inside of it changing). If you want to track the current location of a directory, it is best to open the directory before creating the stream so that you have a file descriptor for it and can issue an F_GETPATH fcntl() to find the current path.

编辑:添加 fcntl 示例

cocoadev 的例子表明作者对指针有点缺乏经验。 pathIntPointer 不仅是不必要的,而且也是导致问题的原因。对 fnctl 返回代码的错误检查会捕获它。这是回调的修订版本:

void fsevents_callback(ConstFSEventStreamRef streamRef, 
void *userData,
size_t numumberOfEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[]) {

MyAppController *appController = (MyAppController *)userData;
char newPath[ MAXPATHLEN ];
int rc;

rc = fcntl( appController.watchedDirectoryFileDescriptor, F_GETPATH, newPath );
if ( rc == -1 ) {
perror( "fnctl F_GETPATH" );
return;
}

NSString *newPathString = [[NSString alloc] initWithUTF8String: newPath ];
NSLog(@"newPathString: %@", newPathString);
[ newPathString release ];
}

关于cocoa - 是否可以使用 FSEvents 获取文件夹已移动的通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5799003/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com