问题
I have made this little code to check how many subdirectories are in a given directory. It checks only the first level, is there anyway I can make it simplier? I have added comments, maybe easier to understand my intention. Thank you!
#import < Foundation/Foundation.h > int main (int argc, const char * argv[]){
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// insert code here...
NSFileManager *filemgr;
NSMutableArray *listOfFiles;
NSDictionary *listOfFolders;
NSDictionary *controllDir;
int i, count;
NSString *myPath;
filemgr = [NSFileManager defaultManager];
myPath = @"/";
// list the files in the given directory (myPath)
listOfFiles = [filemgr directoryContentsAtPath: myPath];
// count the number of elements in the array
count = [listOfFiles count];
// check them one by one
for (i = 0; i < count; i++)
{
// I need the full path
NSString *filePath =[NSString stringWithFormat:@"%@/%@", myPath, [listOfFiles objectAtIndex: i]];
// add every item with its attributes
listOfFolders = [filemgr attributesOfItemAtPath:filePath error:NULL];
// to avoid typo get the attribute and create a string
controllDir = [filemgr attributesOfItemAtPath:@"/" error:NULL];
NSString *toCheck = [NSString stringWithFormat:@"%@", [controllDir objectForKey:NSFileType]];
// the folder elements one by one
NSString *fileType = [NSString stringWithFormat:@"%@", [listOfFolders objectForKey:NSFileType]];
if([toCheck isEqualToString:fileType])
{
NSLog(@"NAME: %@ TYPE: %@" ,[listOfFiles objectAtIndex:i],[listOfFolders objectForKey:NSFileType]);
}
}
[pool drain];
return 0;
}
回答1:
NSURL *url = [NSURL fileURLWithPath:@"/Users"];
NSError *error;
NSArray *items = [[NSFileManager defaultManager]
contentsOfDirectoryAtURL:url
includingPropertiesForKeys:[NSArray array]
options:0
error:&error];
NSMutableArray *dirs = [NSMutableArray array];
for (NSURL *url in items) {
if (CFURLHasDirectoryPath((CFURLRef)url)) {
[dirs addObject:url];
}
}
}
You can get fancy with blocks this way:
NSPredicate *predicate = [NSPredicate predicateWithBlock:
^BOOL (id evaluatedObject, NSDictionary *bindings){
return CFURLHasDirectoryPath((CFURLRef)evaluatedObject); }];
NSArray *dirs = [items filteredArrayUsingPredicate:predicate]);
Of note here is that it only hits the disk the one time, and it doesn't spend any time fetching unneeded attributes. Once you construct the NSURL, you can always tell if it's a directory because it ends in a / (this is specified behavior). That's all CFURLHasDirectoryPath() is doing. It doesn't actually hit the disk.
回答2:
Brief thoughts (posting from a cell phone):
- use an NSDirectoryEnumerator.
- it has a method called fileAttributes that will return an
NSDictionarywith the item's attributes. NSDictionaryhas afileTypemethod that will return a constant to indicate the kind of the item.- there's a nice constant called
NSFileTypeDirectoryyou can use for comparison.
回答3:
How's this?
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error;
NSArray *subpaths = [fm contentsOfDirectoryAtPath:myPath error:&error];
if (!subpaths) ...handle error.
NSMutableArray *subdirs = [NSMutableArray array];
for (NSString *name in subpaths)
{
NSString *subpath = [myPath stringByAppendingPathComponent:name];
BOOL isDir;
if ([fm fileExistsAtPath:subpath isDirectory:&isDir] &&
isDir)
{
[subdirs addObject:subpath];
}
}
Now the subdirs array contains all of the immediate subdirectories.
来源:https://stackoverflow.com/questions/4899720/check-the-attribute-of-items-in-a-directory-in-objective-c