知道对象是否是文件夹的资源最少的方法是什么?

时间:2015-05-31 16:55:14

标签: ios objective-c directory nsfilemanager

我需要为文件和文件夹排序8145个对象(可能还有更多)。 (在A8X上测试过)。

第一种方法。

for(NSString *filename in FilesList) //This method takes an average of 7.7 seconds.
{
    fileExtension = (__bridge CFStringRef)[filename pathExtension];
    fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
    if ([­[­[­[NSFileManager defaultManager] attributesOfItemAtPath:[FolderPath stringByAppendingPathComponent:filename] error:nil] fileType] isEqualToString:@"NSFileTypeDirectory"] && !UTTypeConformsTo(fileUTI, kUTTypeRTFD))
       [OnlyFolderList addObject:filename];
    else
       [OnlyFilesList addObject:filename];
}

第二种方法。

for(NSString *filename in FilesList) //This method takes an average of 2.9 seconds.
{
     fileExtension = (__bridge CFStringRef)[filename pathExtension];
     fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
      [[NSFileManager defaultManager] fileExistsAtPath:[FolderPath stringByAppendingPathComponent:filename] isDirectory:&isDir];
      if (isDir && !UTTypeConformsTo(fileUTI, kUTTypeRTFD))
          [OnlyFolderList addObject:filename];
      else
          [OnlyFilesList addObject:filename];
}

你知道更快的方法吗?

-----使用添加最快的方法更新----- // 8165个对象的0.26秒!

    NSNumber *isDirectory;
    NSError *error = nil;
    NSString *name;
    NSArray *FilesList = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:FolderPath] includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLIsDirectoryKey,NSURLNameKey,nil] options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];
    for (NSURL *url in FilesList)
    {
       [url getResourceValue:&name forKey:NSURLNameKey error:&error];
       [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error];
       if ([isDirectory boolValue])
       {
           CFStringRef fileExtension = (__bridge CFStringRef)[name pathExtension];
           CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
           if (!UTTypeConformsTo(fileUTI, kUTTypeRTFD))
               [OnlyFolderList addObject:name];
           else
               [OnlyFilesList addObject:name];
       }
       else
           [OnlyFilesList addObject:name];
    }

3 个答案:

答案 0 :(得分:3)

尝试使用contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:

NSURL *root = ... // the root URL to get the file list from
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *filesList = [fm contentsOfDirectoryAtURL:root includingPropertiesForKeys:@[ NSURLIsDirectoryKey, NSURLTypeIdentifierKey ] options:NSDirectoryEnumerationSkipsHiddenFiles error:&error];
if (dirURLs) {
    for (NSURL *fileURL in filesList) {
        NSString *filename = [[fileURL path] lastPathComponent];
        NSNumber *isDir = nil;
        [fileURL getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:nil]
        if ([isDir boolValue]) {
            NSString *uti;
            [fileURL getResourceValue:&uti forKey:NSURLTypeIdentifierKey error:nil];
            if ([(__bridge NSString *)kUTTypeRTFD isEqualToString:uti]) {
                [OnlyFilesList addObject:filename];
            } else {
                [OnlyFoldersList addObject:filename];
            }
        } else {
            [OnlyFilesList addObject:filename];
        }
    }
} else {
    NSLog(@"Unable to get list of files in %@: %@", root, error);
}

答案 1 :(得分:1)

在第二种方法中,在isDir的测试中移动fileExtension和fileUTI,这样如果文件不是潜在的目录,代码就不会运行。

试试这个:

NSFileManager *fileManager = [NSFileManager defaultManager];
for(NSString *filename in FilesList) {
    [fileManager fileExistsAtPath:[FolderPath stringByAppendingPathComponent:filename] isDirectory:&isDir];
    if (isDir) {
        CFStringRef fileExtension = (__bridge CFStringRef)[filename pathExtension];
        CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
        if (!UTTypeConformsTo(fileUTI, kUTTypeRTFD))
            [OnlyFolderList addObject:filename];
        else
            [OnlyFilesList addObject:filename];
    }
    else
        [OnlyFilesList addObject:filename];
}

答案 2 :(得分:1)

尝试直接使用BSD API。

static BOOL cStringHasSuffix(const char *string, const char *suffix) {
    unsigned long stringLength = strlen(string);
    unsigned long suffixLength = strlen(suffix);
    return stringLength >= suffixLength && memcmp(string + stringLength - suffixLength, suffix, suffixLength) == 0;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSURL *url = [[NSBundle mainBundle] bundleURL];
    NSMutableArray *folderNames = [NSMutableArray array];
    NSMutableArray *fileNames = [NSMutableArray array];
    const char *rtfdSuffix = ".rtfd";
    DIR *dir = opendir(url.fileSystemRepresentation);
    struct dirent *item;
    while ((item = readdir(dir))) {
        NSString *name = [NSString stringWithUTF8String:item->d_name];
        if (item->d_type == 0) {
            NSLog(@"unknown type for %@", name);
        } else if (item->d_type == DT_DIR) {
            if (cStringHasSuffix(item->d_name, rtfdSuffix)) {
                [fileNames addObject:name];
            } else {
                [folderNames addObject:name];
            }
        } else if (item->d_type == DT_REG) {
            [fileNames addObject:name];
        } else {
            NSLog(@"unexpected type %d for %@", item->d_type, name);
        }
    }
    closedir(dir);

    NSLog(@"fileNames = %@", fileNames);
    NSLog(@"folderNames = %@", folderNames);
    return YES;
}