问题
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
NSDictionary
with the item's attributes. NSDictionary
has afileType
method that will return a constant to indicate the kind of the item.- there's a nice constant called
NSFileTypeDirectory
you 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