objective-c cocoa macos iteration folders

objective c - Iterar a través de archivos en una carpeta con carpetas anidadas-Cocoa



objective-c macos (5)

Necesito acceder a todos los archivos en una carpeta, incluido el archivo que existe dentro de las carpetas anidadas. Una carpeta de ejemplo podría verse así.

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

Digamos que quería ejecutar un proceso en cada archivo dentro de "animales" que no es una carpeta. ¿Cuál sería la mejor manera de recorrer la carpeta "animals" y todas sus subcarpetas para acceder a cada archivo?

Gracias.


Aquí hay una solución que usa -subpathsOfDirectoryAtPath:rootPath , con URLs de archivos y modernas campanas y silbidos de nulabilidad de Objective-C.

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

... y lo mismo en 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)) } }


Aquí hay una versión rápida:

func openEachFileAt(path: String) { var file: String var subs = NSFileManager.defaultManager().subpathsOfDirectoryAtPath(path, error: nil) as! [String] var totalFiles = subs.count println(totalFiles) for sub in subs { if sub.rangeOfString(".DS_Store") != nil { //a DS_Store file } else if sub.rangeOfString(".xcassets") != nil { //a xcassets file } else if (sub as NSString).substringWithRange(NSRange(location: 0, length: 4)) == ".git" { //a git file } else if sub.pathExtension == "swift" { //a swift file } else if sub.pathExtension == "m" { //a objc file } else if sub.pathExtension == "h" { //a header file } else { } var fullPath = path.stringByAppendingPathComponent(sub) } }


Este código funcionó para mí.

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''s 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''s 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''s a file BOOL fileExistsAtPath = [[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory]; if (fileExistsAtPath) { if (!isDirectory) //its a file { //Do with file } else{ //it''s a folder, so recurse [self enumerateFolder:file]; } } else printf("/nenumeratefolder No file at path %s",[file UTF8String]); } }


Tal vez puedas usar algo como esto:

+(void)openEachFileAt:(NSString*)path { NSString* file; NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:path]; while (file = [enumerator nextObject]) { // check if it''s 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]; } } }


Use NSDirectoryEnumerator para enumerar recursivamente los archivos y directorios en el directorio que desee, y pídale que le diga si se trata de un archivo o directorio. Lo siguiente se basa en el ejemplo enumerado en la documentación para -[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 } }