gpt4 book ai didi

c++ - Mac OS X 的文件系统观察器

转载 作者:行者123 更新时间:2023-11-30 02:56:47 26 4
gpt4 key购买 nike

目前我们使用QFileSystemWatcher,属于Qt。由于在 Mac OS X 中的支持有限,它只能通知我们两个事件:目录更改或文件更改。

但后一个事件(文件改变)在文件大小稍大,写入磁盘时间稍长时会多次触发。

我们的解决方法是设置一个计时器,在 1 秒内检查文件。如果在计时器到期之前收到更多有关该文件的信号,我们将重置计时器。

有没有办法在文件写入磁盘(写入完成)时得到通知?不必局限于Qt,任何库都可以。


我们知道 kqueue 监控方法,但它的级别太低,我们不想对每个文件都这样做,因为我们正在监控文件系统的很大一部分..

最佳答案

我在一个项目中遇到了同样的问题,最后我决定实现一个native watcher。这很简单:

在.h中:

class OSXWatcher : public Watcher
{
public:

OSXWatcher(const QString& strDirectory);
virtual ~OSXWatcher();

virtual bool Start();
virtual bool Stop();

private:

/**
* Callback function of the OS X FSEvent API.
*/
static void fileSystemEventCallback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]);

FSEventStreamRef stream;
};

.cpp:

bool OSXWatcher::Start()
{
CFStringRef pathToWatchCF = CFStringCreateWithCString(NULL, this->dirToWatch.toUtf8().constData(), kCFStringEncodingUTF8);
CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&pathToWatchCF, 1, NULL);

FSEventStreamContext context;
context.version = 0;
context.info = this;
context.retain = NULL;
context.release = NULL;
context.copyDescription = NULL;

stream = FSEventStreamCreate(NULL, &OSXWatcher::fileSystemEventCallback, &context, pathsToWatch, kFSEventStreamEventIdSinceNow, 3.0, kFSEventStreamCreateFlagFileEvents);
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(stream);

CFRelease(pathToWatchCF);

// Read the folder content to protect any unprotected or pending file
ReadFolderContent();
}

bool OSXWatcher::Stop()
{
FSEventStreamStop(stream);
FSEventStreamInvalidate(stream);
FSEventStreamRelease(stream);
}

void OSXWatcher::fileSystemEventCallback(ConstFSEventStreamRef /*streamRef*/, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[])
{
char **paths = (char **)eventPaths;

for (size_t i=0; i<numEvents; i++) {
// When a file is created we receive first a kFSEventStreamEventFlagItemCreated and second a (kFSEventStreamEventFlagItemCreated & kFSEventStreamEventFlagItemModified)
// when the file is finally copied. Catch this second event.
if (eventFlags[i] & kFSEventStreamEventFlagItemCreated
&& eventFlags[i] & kFSEventStreamEventFlagItemModified
&& !(eventFlags[i] & kFSEventStreamEventFlagItemIsDir)
&& !(eventFlags[i] & kFSEventStreamEventFlagItemIsSymlink)
&& !(eventFlags[i] & kFSEventStreamEventFlagItemFinderInfoMod)) {

OSXWatcher *watcher = (OSXWatcher *)clientCallBackInfo;
if (watcher->FileValidator(paths[i]))
emit watcher->yourSignalHere();
}
}
}

关于c++ - Mac OS X 的文件系统观察器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15194662/

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