2

如果我只需要知道文件是否是文件夹/符号链接及其大小,是否可以使用更快的文件系统 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];
4

3 回答 3

3

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

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

于 2013-02-27T05:05:51.860 回答
1

是否更快我不确定,但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

这是作为已弃用的文件管理器功能的替代品,该功能用于旧 Cocoa-dev 线程FSGetCatalogInfo()中的解决方案,Dave DeLong 对此表示赞许

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

于 2013-02-27T03:47:21.803 回答
1

您可以使用statlstat. 查看此答案以计算目录大小。
CPU 使用 attributesOfItemAtPath:error 引发:

于 2013-02-27T04:53:22.047 回答