jarrodhroberson
2/14/2014 - 3:36 AM

Recursively list all files and directories below a given directory

Recursively list all files and directories below a given directory

/*
 This is example code of how to walk a directory recurisively
 and create a flat list of fully qualified names for all the files
 and directories under the supplied virtual root directory.
 */
#import <CoreServices/CoreServices.h>
#import <AppKit/AppKit.h>
#import <stdarg.h>

int main (int argc, const char * argv[])
{
    int result = EXIT_SUCCESS;
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSUserDefaults *args = [NSUserDefaults standardUserDefaults];
    NSString *dir = [args stringForKey:@"file"];
    NSMutableSet *contents = [[[NSMutableSet alloc] init] autorelease];
    NSFileManager *fm = [NSFileManager defaultManager];
    BOOL isDir;
    if (dir && ([fm fileExistsAtPath:dir isDirectory:&isDir] && isDir))
    {
        if (![dir hasSuffix:@"/"]) 
        {
            dir = [dir stringByAppendingString:@"/"];
        }

        // this walks the |dir| recurisively and adds the paths to the |contents| set
        NSDirectoryEnumerator *de = [fm enumeratorAtPath:dir];
        NSString *f;
        NSString *fqn;
        while ((f = [de nextObject]))
        {
            // make the filename |f| a fully qualifed filename
            fqn = [dir stringByAppendingString:f];
            if ([fm fileExistsAtPath:fqn isDirectory:&isDir] && isDir)
            {
                // append a / to the end of all directory entries
                fqn = [fqn stringByAppendingString:@"/"];
            }
            [contents addObject:fqn];
        }
        
        NSString *fn;
        // here we sort the |contents| before we display them
        for ( fn in [[contents allObjects] sortedArrayUsingSelector:@selector(compare:)] )
        {
            printf("%s\n",[fn UTF8String]);
        }
    }
    else
    {
        printf("%s must be directory and must exist\n", [dir UTF8String]);
        result = EXIT_FAILURE;
    }
    
    [pool drain];
    return result;
}