使用嵌套文件夹遍历文件夹中的文件 – Cocoa
我需要访问文件夹中的每个文件,包括存在于嵌套文件夹中的文件。 示例文件夹可能如下所示。
animals/ -k.txt -d.jpg cat/ -r.txt -z.jpg tiger/ -a.jpg -p.pdf dog/ -n.txt -f.jpg -p.pdf
假设我想对“动物”中不是文件夹的每个文件运行一个进程。 遍历“动物”文件夹及其所有子文件夹来访问每个文件的最佳方式是什么?
谢谢。
使用NSDirectoryEnumerator
recursion枚举所需目录下的文件和目录,并要求它告诉你它是一个文件还是目录。 以下是基于文档中列出的示例-[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 } }
也许你可以使用这样的东西:
+(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]; } } }
这是一个很快的版本:
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) } }
这是一个使用-subpathsOfDirectoryAtPath:rootPath
的解决scheme,带有文件URL和现代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
…和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)) } }
此代码为我工作。
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]); } }