【问题标题】:OS X faster file system API than repetitively calling [NSFileManager attributesOfItemAtPath...]?OS X 比重复调用 [NSFileManager attributesOfItemAtPath...] 更快的文件系统 API?
【发布时间】:2013-02-27 03:30:05
【问题描述】:

如果我只需要知道文件是否为文件夹/符号链接及其大小,是否可以使用更快的文件系统 API。我目前正在使用 [NSFileManager attributesOfItemAtPath...] 并且只有 NSFileSize 和 NSFileType。

是否有我应该使用的批量文件系统枚举 API?我怀疑这可能会更快,而无需跳入和跳出用户代码。

我的目标是通过目录快速递归以获得文件夹的真实文件大小,当前调用 attributesOfItemAtPath 是我 95% 的瓶颈。

我目前正在使用的一些代码:

NSDictionary* properties = [fileManager attributesOfItemAtPath:filePath error:&error];
long long fileSize = [[properties objectForKey:NSFileSize] longLongValue];
NSObject* fileType = [[properties objectForKey:NSFileType isEqual:NSFileTypeDirectory];

【问题讨论】:

标签: objective-c c performance cocoa nsfilemanager


【解决方案1】:

如果你想变得更复杂,Mac OS 内核实现了一个独特的getdirentriesattr() 系统调用,它将从指定目录返回文件列表属性。设置和调用很麻烦,并且并非所有文件系统都支持它(!),但如果你能让它为你工作,它可以显着加快速度。

还有一个密切相关的searchfs() 系统调用,可用于快速搜索文件。它受制于大多数相同的陷阱。

【讨论】:

  • 嗨,我刚刚发现了 searchfs,我正在寻找一个在其输出缓冲区中检索文件完整路径的示例。到目前为止,我一直收到 errno EINVAL,这意味着我的参数组合到 searchfs 不知何故不受支持。也许,如果您有使用此命令的任何经验,您可以向我指出一个相关示例(我在网上找不到)。谢谢!
  • @Zohar81 github.com/sveinbjornt/searchfs 怎么样?
【解决方案2】:

您可以使用statlstat。看看this answer 计算目录大小。
CPU raises with attributesOfItemAtPath:error:

【讨论】:

    【解决方案3】:

    是否更快我不确定,但NSURL 会通过getResourceValue:forKey:error: 为您提供此信息

    NSError * e;
    NSNumber * isDirectory;
    BOOL success = [URLToFile getResourceValue:&isDirectory
                                        forKey:NSURLIsDirectoryKey 
                                         error:&e];
    if( !success ){
       // error
    }
    
    NSNumber * fileSize;
    BOOL success = [URLToFile getResourceValue:&fileSize
                                        forKey:NSURLFileSizeKey
                                         error:&e];
    

    如果您并不真正关心错误,您可能还会发现将其包装起来很方便:

    @implementation NSURL (WSSSimpleResourceValueRetrieval)
    
    - (id)WSSResourceValueForKey: (NSString *)key
    {
        id value = nil;
        BOOL success = [self getResourceValue:&value
                                       forKey:key 
                                        error:nil];
        if( !success ){
            value = nil;
        }
        
        return value;
    }
    
    @end
    

    这是作为已弃用的文件管理器函数 FSGetCatalogInfo() 的替代品,该函数用于 an old Cocoa-dev thread 中 Dave DeLong gives the thumbs up to 的解决方案中。

    对于枚举部分,文件系统编程指南有一节"Getting the Contents of a Directory in a Single Batch Operation",讨论使用contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:

    【讨论】:

    • +1 最后一点很重要——如果使用 Cocoa API,请使用诸如 contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:(或等效枚举器)之类的 API,并仅获取您需要的内容。
    猜你喜欢
    • 2014-01-14
    • 2014-08-17
    • 2012-07-16
    • 1970-01-01
    • 2016-01-16
    • 2011-03-26
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    相关资源
    最近更新 更多