迭代具有嵌套文件夹的文件夹中的文件 - Cocoa

发布于 2024-11-02 11:50:50 字数 281 浏览 1 评论 0原文

我需要访问文件夹中的每个文件,包括嵌套文件夹中存在的文件。示例文件夹可能如下所示。

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

假设我想对“动物”中不是文件夹的每个文件运行一个进程。迭代文件夹“animals”及其所有子文件夹以访问每个文件的最佳方法是什么?

谢谢。

I need to access every file in a folder, including file that exist within nested folders. 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 run a process on every file within "animals" that isn't folder. What would be the best way to iterate through the folder "animals" and all of its subfolders to access every file?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

挽心 2024-11-09 11:50:50

使用NSDirectoryEnumerator递归枚举你想要的目录下的文件和目录,并要求它告诉你它是文件还是目录。以下内容基于 -[NSFileManager enumeratorAtURL:includePropertiesForKeys: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:^BOOL(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
    }
}

Use NSDirectoryEnumerator to recursively enumerate files and directories under the directory you want, and ask it to tell you whether it is a file or directory. The following is based on the example listed at 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:^BOOL(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
    }
}
嘿咻 2024-11-09 11:50:50

也许你可以使用这样的东西:

+(void)openEachFileAt:(NSString*)path
{
  NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:path];
  for (NSString * file in enumerator)
  {
     // 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];
    }
  }
}

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'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];
    }
  }
}
不疑不惑不回忆 2024-11-09 11:50:50

这是一个快速版本:

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.hasSuffix(".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)
    }
}

Here is a swift 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.hasSuffix(".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)
    }
}
动次打次papapa 2024-11-09 11:50:50

这是使用 -subpathsOfDirectoryAtPath:rootPath,带有文件 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))
    }
}

Here's a solution using -subpathsOfDirectoryAtPath:rootPath, with file URLs and modern Objective-C nullability bells & 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))
    }
}
秋叶绚丽 2024-11-09 11:50:50

这段代码对我有用。

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]);
        }
    }

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'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]);
        }
    }
多像笑话 2024-11-09 11:50:50

在 Swift 中我们可以尝试以下操作。

let docsDir = NSHomeDirectory().appending("/Documents")
let localFileManager = FileManager()

let dirEnum = localFileManager.enumerator(atPath: docsDir)

while let file = dirEnum?.nextObject() as? String {
    if file.hasSuffix(".doc") {
        print(docsDir.appending("/\(file)"))
    }
}

参考
https://developer.apple.com/documentation/foundation/filemanager/1408726-枚举器

In Swift we can try the following.

let docsDir = NSHomeDirectory().appending("/Documents")
let localFileManager = FileManager()

let dirEnum = localFileManager.enumerator(atPath: docsDir)

while let file = dirEnum?.nextObject() as? String {
    if file.hasSuffix(".doc") {
        print(docsDir.appending("/\(file)"))
    }
}

Reference
https://developer.apple.com/documentation/foundation/filemanager/1408726-enumerator

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文