Reputation: 636
Is there a way to tell the -[NSFileManager contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:]
method to exclude directory names when gathering the contents of a directory?
I have a tree view showing folders and want to show ONLY files in the table view, but I can't seem to find a key or any other way to exclude folders. I suppose I could iterate the returned array to stuff only files into a second array, which will be used as the data source, but this double-handling seems a bit dodgy.
I also tried returning nil
from the tableView:viewForTableColumn:row:
method if the NSURL
was a directory, but that only results in a blank row in the table, so that's no good either.
Surely there is a way to just tell NSFileManager
that I only want files?
Upvotes: 6
Views: 10976
Reputation: 64022
There's no way around getting the contents including directories and then paring them down from there, but that's not really a problem.
The NSURL
s you get from the file manager will tell you if the file system object each represents is a directory, as long as you include the NSURLIsDirectoryKey
item in the "properties for keys" list.
There's any number of ways to filter the array using that information after you've got it -- or by enumerating, as the other answers demonstrate.
You could add an accessor method to NSURL
:
@implementation NSURL (RWIsDirectory)
- (BOOL)RWIsDirectory
{
NSNumber * isDir;
[self getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:NULL];
return [isDir boolValue];
}
@end
Then use a predicate:
[directoryContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"RWIsDirectory == NO"]];
Upvotes: 3
Reputation: 318904
The best options is to use enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:
to populate an array that excludes folders.
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];
}
}
This will give you an array of NSURL
objects representing the files.
Upvotes: 11
Reputation: 89549
You can go a little deeper with a directory enumerator.
How about this?
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
Upvotes: 15