gpt4 book ai didi

c - OSX FSEventStreamEventFlags 无法正常工作

转载 作者:太空狗 更新时间:2023-10-29 16:36:24 24 4
gpt4 key购买 nike

我正在监视文件系统事件的目录。除了一个异常(exception),一切似乎都运行良好。当我第一次创建文件时,它吐出它已创建。然后我可以删除它,它说它已被删除。当我再次创建同一个文件时,我同时获得了一个已创建和已删除的标志。我显然误解了在调用回调时如何设置标志。这里发生了什么?

//
// main.c
// GoFSEvents
//
// Created by Kyle Cook on 8/22/13.
// Copyright (c) 2013 Kyle Cook. All rights reserved.
//

#include <CoreServices/CoreServices.h>
#include <stdio.h>
#include <string.h>

void eventCallback(FSEventStreamRef stream, void* callbackInfo, size_t numEvents, void* paths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) {
char **pathsList = paths;

for(int i = 0; i<numEvents; i++) {
uint32 flag = eventFlags[i];

uint32 created = kFSEventStreamEventFlagItemCreated;
uint32 removed = kFSEventStreamEventFlagItemRemoved;

if(flag & removed) {
printf("Item Removed: %s\n", pathsList[i]);
}
else if(flag & created) {
printf("Item Created: %s\n", pathsList[i]);
}
}
}

int main(int argc, const char * argv[])
{
CFStringRef mypath = CFSTR("/path/to/dir");
CFArrayRef paths = CFArrayCreate(NULL, (const void **)&mypath, 1, NULL);

CFRunLoopRef loop = CFRunLoopGetMain();
FSEventStreamRef stream = FSEventStreamCreate(NULL, (FSEventStreamCallback)eventCallback, NULL, paths, kFSEventStreamEventIdSinceNow, 1.0, kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagNoDefer);
FSEventStreamScheduleWithRunLoop(stream, loop, kCFRunLoopDefaultMode);
FSEventStreamStart(stream);

CFRunLoopRun();

FSEventStreamStop(stream);
FSEventStreamInvalidate(stream);
FSEventStreamRelease(stream);

return 0;
}

最佳答案

据我所知,您必须寻找 kFSEventStreamEventFlagItemRemovedkFSEventStreamEventFlagItemCreated,然后使用 stat() 或类似的检查文件是否确实被添加或删除。 FSEvents 文档似乎暗示了这一点。

看起来 API 正在对事件位进行“或”运算……所以实际上它是自创建 FSEventsListener 以来所做的所有更改的“或”运算。由于情况似乎如此,另一种选择可能是每次都创建一个新的 FSEventListener(并使用合并计时器选项)。

我做了一些谷歌搜索,但没有找到这个问题的其他示例,甚至没有找到苹果示例代码,但我并没有花太长时间。

我以前使用过 kqueue API:https://gist.github.com/nielsbot/5155671 (这个要点是一个围绕 kqueue 的 obj-c 包装器)

我更改了您的示例代码以显示为每个 FSEvent 设置的所有标志:

#include <CoreServices/CoreServices.h>
#include <stdio.h>
#include <string.h>

static int __count = 0 ;
void eventCallback(FSEventStreamRef stream, void* callbackInfo, size_t numEvents, void* paths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) {
char **pathsList = paths;

printf("callback #%u\n", ++__count ) ;
const char * flags[] = {
"MustScanSubDirs",
"UserDropped",
"KernelDropped",
"EventIdsWrapped",
"HistoryDone",
"RootChanged",
"Mount",
"Unmount",
"ItemCreated",
"ItemRemoved",
"ItemInodeMetaMod",
"ItemRenamed",
"ItemModified",
"ItemFinderInfoMod",
"ItemChangeOwner",
"ItemXattrMod",
"ItemIsFile",
"ItemIsDir",
"ItemIsSymlink",
"OwnEvent"
} ;

for(int i = 0; i<numEvents; i++)
{
printf("%u\n", i ) ;
printf("\tpath %s\n", pathsList[i]) ;
printf("\tflags: ") ;
long bit = 1 ;
for( int index=0, count = sizeof( flags ) / sizeof( flags[0]); index < count; ++index )
{
if ( ( eventFlags[i] & bit ) != 0 )
{
printf("%s ", flags[ index ] ) ;
}
bit <<= 1 ;
}
printf("\n") ;
}

FSEventStreamFlushSync( stream ) ;

}

int main(int argc, const char * argv[])
{
CFStringRef path = CFStringCreateWithCString( kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8 ) ;
CFArrayRef paths = CFArrayCreate(NULL, (const void **)&path, 1, &kCFTypeArrayCallBacks );
if ( path ) { CFRelease( path ) ; }

CFRunLoopRef loop = CFRunLoopGetCurrent() ;
FSEventStreamRef stream = FSEventStreamCreate(NULL, (FSEventStreamCallback)eventCallback, NULL, paths, kFSEventStreamEventIdSinceNow, 0, kFSEventStreamCreateFlagFileEvents );
if ( paths ) { CFRelease( paths ) ; }

FSEventStreamScheduleWithRunLoop(stream, loop, kCFRunLoopDefaultMode);
FSEventStreamStart(stream);

CFRunLoopRun() ;

FSEventStreamStop(stream);
FSEventStreamInvalidate(stream);
FSEventStreamRelease(stream);

return 0;
}

关于c - OSX FSEventStreamEventFlags 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18415285/

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