ios - 我可以使用dispatch_io检测给定目录中的文件创建吗?

标签 ios file io grand-central-dispatch

好像我可以创建一种DISPATCH_SOURCE_TYPE_VNODE类型的dispatch_source并提供我感兴趣的目录的文件描述符,但是我不确定应该设置哪些标志来检测文件的创建。

我最终要做的是使用dispatch_io_read附加一个开始,以在写入文件时从文件中读取数据,但是为此,我需要文件的文件描述符,该文件描述符在创建之前不可用。

为了清楚起见,我不会直接创建文件,因此无法轻松确定(不进行轮询)该文件何时存在。

最佳答案

以下是您如何使用GCD的示例:

@implementation AppDelegate
{
    dispatch_source_t _source;
    NSArray* mFiles;
    NSString* mPath;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Add an observer
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(directoryDidChange:) name:@"FilesChanged" object:self];

    mPath = @"/your/dir";

    int fildes = open(mPath.UTF8String, O_RDONLY);

    dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);

    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fildes, DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE, queue);

    dispatch_source_set_event_handler(source, ^{
        [self updateListWithNotification: YES];
    });

    dispatch_source_set_cancel_handler(source, ^{
        close((int)dispatch_source_get_handle(source));
    });

    _source = source;

    dispatch_resume(source); // Start monitoring

    dispatch_async(queue, ^{
        [self updateListWithNotification: NO];
    });
}

- (void)applicationWillTerminate:(NSNotification *)notification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"FilesChanged" object:self];
    dispatch_source_cancel(_source); // Stop monitoring
}

- (void)updateListWithNotification: (BOOL)withNotification
{
    // Our manipulation of state here is OK because we know this only ever gets called on a serial queue
    mFiles = mFiles ?: [NSArray array];

    NSArray* contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: mPath error: nil] ?: [NSArray array];

    if (withNotification)
    {
        NSSet* oldFiles = [NSSet setWithArray: mFiles];
        NSSet* newFiles = [NSSet setWithArray: contents];

        NSMutableSet* addedFiles = [newFiles mutableCopy]; [addedFiles minusSet: oldFiles];
        NSMutableSet* removedFiles = [oldFiles mutableCopy]; [removedFiles minusSet: newFiles];
        NSDictionary* ui = @{ @"FilesRemoved" : removedFiles, @"FilesAdded" : addedFiles };
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName: @"FilesChanged" object: self userInfo: ui];
        });
    }

    mFiles = contents;
}


- (void)directoryDidChange: (NSNotification*)n
{
    NSLog(@"Directory %@ changed.\nFiles removed: %@\nFiles added: %@", mPath, n.userInfo[@"FilesRemoved"], n.userInfo[@"FilesAdded"]);
}

@end

这将使用GCD监视目录,然后将NSNotification发布到主线程,其中包含自上次通知以来添加和删除的一组文件。

关于ios - 我可以使用dispatch_io检测给定目录中的文件创建吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23513943/

相关文章:

ios - 使用 Xcode 和 Cocoapods 加速构建

ios - UITableViewCell 没有扩展以适应 UILabel 的高度,我做错了什么?

c++ - 在 netbeans IDE 中将 "media"文件添加到 c/c++ 项目的适当方法

Python文件读写

iOS Unwind Segue 嵌入导航 Controller 时停止工作

ios - 处理复杂的 Firebase 数据库查询的 null 返回

php - 使用 PHP 和 CURL 下载 htaccess 保护的文件

haskell - Haskell 内部的 IO 实现

c - 带有管道的简单主函数中的错误文件号

linux - 调用具有用户界面的外部程序的 Shell 脚本