Iterating through files in a folder with subfolders - Cocoa

I need to access every file in a folder, including a file that exists in subfolders. An example folder might look like this.

animals/ -k.txt -d.jpg cat/ -r.txt -z.jpg tiger/ -a.jpg -p.pdf dog/ -n.txt -f.jpg -p.pdf 

Say that I wanted to start the process in each file in "animals", which is not a folder. What would be the best way to iterate over the animals folder and all its subfolders to access each file?

Thank.

+40
directory iteration objective-c cocoa folders macos
Apr 21 2018-11-21T00:
source share
5 answers

Use NSDirectoryEnumerator to recursively list files and directories in the correct directory and ask him to tell you if it is a file or directory. Below is an example given in the documentation for -[NSFileManager enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:] :

 NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *directoryURL = … // URL pointing to the directory you want to browse NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey]; NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:directoryURL includingPropertiesForKeys:keys options:0 errorHandler:^(NSURL *url, NSError *error) { // Handle the error. // Return YES if the enumeration should continue after the error. return YES; }]; for (NSURL *url in enumerator) { NSError *error; NSNumber *isDirectory = nil; if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) { // handle error } else if (! [isDirectory boolValue]) { // No error and it's not a directory; do something with the file } } 
+94
Apr 21 2018-11-21T00:
source share

Maybe you can use something like this:

 +(void)openEachFileAt:(NSString*)path { NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:path]; for (NSString * file in enumerator) { // check if it a directory BOOL isDirectory = NO; NSString* fullPath = [path stringByAppendingPathComponent:file]; [[NSFileManager defaultManager] fileExistsAtPath:fullPath isDirectory: &isDirectory]; if (!isDirectory) { // open your file (fullPath)… } else { [self openEachFileAt: fullPath]; } } } 
+25
Apr 21 2018-11-21T00:
source share

Here is the quick version:

 func openEachFile(inDirectory path: String) { let subs = try! FileManager.default.subpathsOfDirectory(atPath: path) let totalFiles = subs.count print(totalFiles) for sub in subs { if sub.hasPrefix(".DS_Store") { //a DS_Store file } else if sub.hasSuffix(".xcassets") { //a xcassets file } else if (sub as NSString).substring(to: 4) == ".git" { //a git file } else if sub.hasSuffix(".swift") { //a swift file } else if sub.hasSuffix(".m") { //a objc file } else if sub.hasSuffix(".h") { //a header file } else { // some other file } let fullPath = (path as NSString).appendingPathComponent(sub) } } 
+14
Jun 30 '15 at 22:47
source share

This code worked for me.

 NSMutableString *allHash; -(NSString*)getIterate:(NSString*)path { allHash = [NSMutableString stringWithString:@""]; NSDirectoryEnumerator *de= [[NSFileManager defaultManager] enumeratorAtPath:path]; NSString *file; BOOL isDirectory; for(file in de) { //first check if it a file NSString* fullPath = [NSString stringWithFormat:@"%@/%@",path,file]; BOOL fileExistsAtPath = [[NSFileManager defaultManager] fileExistsAtPath:fullPath isDirectory:&isDirectory]; NSLog(@"Check=>%d",fileExistsAtPath); if (!isDirectory) //its a file { //Do with filepath } else{ //it a folder, so recurse [self enumerateFolder:fullPath]; } } return allHash; } -(void) enumerateFolder:(NSString*)fileName { NSDirectoryEnumerator *de= [[NSFileManager defaultManager] enumeratorAtPath:fileName]; NSString* file; BOOL isDirectory; for(file in de) { //first check if it a file BOOL fileExistsAtPath = [[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory]; if (fileExistsAtPath) { if (!isDirectory) //its a file { //Do with file } else{ //it a folder, so recurse [self enumerateFolder:file]; } } else printf("\nenumeratefolder No file at path %s",[file UTF8String]); } } 
+1
Jul 15 '16 at 10:36
source share

Here's a solution using -subpathsOfDirectoryAtPath:rootPath , with file URLs and modern bells and whistles.

 typedef void (^FileEnumerationBlock)(NSURL *_Nonnull fileURL); @interface NSFileManager (Extensions) - (void)enumerateWithRootDirectoryURL:(nonnull NSURL *)rootURL fileHandler:(FileEnumerationBlock _Nonnull)fileHandler error:(NSError *_Nullable *_Nullable)error; @end @implementation NSFileManager (Extensions) - (void)enumerateWithRootDirectoryURL:(NSURL *)rootURL fileHandler:(FileEnumerationBlock)fileHandler error:(NSError **)error { NSString *rootPath = rootURL.path; NSAssert(rootPath != nil, @"Invalid root URL %@ (nil path)", rootURL); NSArray *subs = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:rootPath error:error]; if (!subs) { return; } for (NSString *sub in subs) { fileHandler([rootURL URLByAppendingPathComponent:sub]); } } @end 

... and the same in Swift:

 func enumerate(rootDirectoryURL rootURL: NSURL, fileHandler:(URL:NSURL)->Void) throws { guard let rootPath = rootURL.path else { preconditionFailure("Invalid root URL: \(rootURL)") } let subs = try NSFileManager.defaultManager().subpathsOfDirectoryAtPath(rootPath) for sub in subs { fileHandler(URL: rootURL.URLByAppendingPathComponent(sub)) } } 
0
Apr 10 '16 at 19:21
source share



All Articles