NSFileManager列出目录内容,不包括目录。

5
有没有办法告诉-[NSFileManager contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:]方法,在收集目录内容时排除目录名称?
我有一个树形视图显示文件夹,并希望在表格视图中仅显示文件,但我似乎找不到排除文件夹的关键字或其他方法。我想我可以迭代返回的数组以将只有文件的文件夹放入第二个数组中,这将用作数据源,但这种双重处理似乎有点不可靠。
我也尝试如果NSURL是一个目录,则从tableView:viewForTableColumn:row:方法返回nil,但那只会导致表格中出现空白行,所以也不好使。
肯定有一种方法可以告诉NSFileManager,我只需要文件吧?
3个回答

15

你可以使用目录枚举器深入了解一下。

这个怎么样?

NSDirectoryEnumerator *dirEnumerator = [localFileManager enumeratorAtURL:directoryToScan includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLNameKey, NSURLIsDirectoryKey,nil] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants  errorHandler:nil];
NSMutableArray *theArray=[NSMutableArray array];

for (NSURL *theURL in dirEnumerator) {

    // Retrieve the file name. From NSURLNameKey, cached during the enumeration.
    NSString *fileName;
    [theURL getResourceValue:&fileName forKey:NSURLNameKey error:NULL];

    // Retrieve whether a directory. From NSURLIsDirectoryKey, also
    // cached during the enumeration.

    NSNumber *isDirectory;
    [theURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL];


    if([isDirectory boolValue] == NO)
    {
        [theArray addObject: fileName];
    }
}

// theArray at this point contains all the filenames

2
+1,因为你比我快了10秒钟,而且答案几乎一模一样。 :) - rmaddy
谢谢您。我想避免重复处理,但如果这是被接受的做法,那么我可以接受它,只要我知道我没有犯下一些粗心的编码违规行为。也感谢大家。虽然我没有足够的经验点来投票支持任何人,但我真的很感激提供的所有解决方案。 - Rainier Wolfcastle
1
你可以直接使用 "![isDirectory boolValue]",布尔值在if语句中不需要与字面量进行比较。 - Alexander

11

最好的选择是使用 enumeratorAtURL:includingPropertiesForKeys:options:errorHandler: 方法来填充一个排除文件夹的数组。

NSFileManager *fm = [[NSFileManager alloc] init];
NSDirectoryEnumerator *dirEnumerator = [fm enumeratorAtURL:directoryToScan
                    includingPropertiesForKeys:@[ NSURLNameKey, NSURLIsDirectoryKey ]
                    options:NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsSubdirectoryDescendants
                    errorHandler:nil];

NSMutableArray *fileList = [NSMutableArray array];

for (NSURL *theURL in dirEnumerator) {
    NSNumber *isDirectory;
    [theURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL];
    if (![isDirectory boolValue]) {
        [fileList addObject:theURL];
    }
}

这将为您提供一个包含表示文件的NSURL对象的数组。


3
你能在我之后10秒钟给出完全相同的答案,我要为你点赞。 - Michael Dautermann

3

获取目录及其内容,然后从中进行筛选是不可避免的,但这并不是真正的问题。

文件管理器获取的NSURL会告诉您每个文件系统对象是否为目录,只要在“键的属性”列表中包括NSURLIsDirectoryKey项即可。

一旦获得了该信息,就有许多方法可以使用它来过滤数组--或者像其他答案演示的那样进行枚举。

您可以为NSURL添加一个存取方法:

@implementation NSURL (RWIsDirectory)

- (BOOL)RWIsDirectory
{
    NSNumber * isDir;
    [self getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:NULL];
    return [isDir boolValue];
}

@end

然后使用谓词:
[directoryContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"RWIsDirectory == NO"]];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接