使用Swift的FileManager迭代文件夹及其子文件夹中的文件

Iac*_*ari 68 cocoa nsfilemanager swift

我是编程Swift的新手,我正在尝试遍历文件夹中的文件.我在这里看了一下答案并试图将其翻译成Swift语法,但没有成功.

let fileManager = NSFileManager.defaultManager()
let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(folderPath)

for element in enumerator {
    //do something
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

Type 'NSDirectoryEnumerator' does not conform to protocol 'SequenceType'
Run Code Online (Sandbox Code Playgroud)

我的目的是查看主文件夹中包含的所有子文件夹和文件,找到具有特定扩展名的所有文件,然后对它们执行某些操作.

pNr*_*Nre 78

使用nextObject()方法enumerator:

while let element = enumerator?.nextObject() as? String {
    if element.hasSuffix("ext") { // checks the extension
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于那些使用`enumerator(at:,includesPropertiesForKeys:,options :)的人来说,考虑到元素实际上是一个URL而不是一个String,所以如果你使用那个代码,它将不会返回任何内容.`while let element = enumerator?.nextObject()as?网址{...}` (6认同)
  • 刚刚尝试过这一点,除了无限循环外,我一无所有,不得不大致采用雷尼尔的方法。 (2认同)

vad*_*ian 54

如今(2017年初),强烈建议使用 - 更通用的 - 与URL相关的API

let fileManager = FileManager.default

do {
    let resourceKeys : [URLResourceKey] = [.creationDateKey, .isDirectoryKey]
    let documentsURL = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    let enumerator = FileManager.default.enumerator(at: documentsURL,
                            includingPropertiesForKeys: resourceKeys,
                                               options: [.skipsHiddenFiles], errorHandler: { (url, error) -> Bool in
                                                        print("directoryEnumerator error at \(url): ", error)
                                                        return true
    })!

    for case let fileURL as URL in enumerator {
        let resourceValues = try fileURL.resourceValues(forKeys: Set(resourceKeys))
        print(fileURL.path, resourceValues.creationDate!, resourceValues.isDirectory!)
    }
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)


Rai*_*tle 18

我根本无法获得pNre的解决方案; while循环从未收到任何东西.但是,我确实遇到过这个适用于我的解决方案(在Xcode 6 beta 6中,所以自从pNre发布上述答案后,情况可能已经发生了变化?):

for url in enumerator!.allObjects {
    print("\((url as! NSURL).path!)")
}
Run Code Online (Sandbox Code Playgroud)

  • 之所以有选票是因为它依赖强制展开枚举器(枚举器!)而不是枚举器?在最高投票的答案. (2认同)

ing*_*nti 7

我从以前的 anwers 那里得到的两分钱.. 更快捷,并且有选项:

 let enumerator = FileManager.default.enumerator(atPath: folderPath)
    while let element = enumerator?.nextObject() as? String {
        print(element)

        if let fType = enumerator?.fileAttributes?[FileAttributeKey.type] as? FileAttributeType{

            switch fType{
            case .typeRegular:
                print("a file")
            case .typeDirectory:
                print("a dir")
            }
        }

    }
Run Code Online (Sandbox Code Playgroud)

  • 这是这里最有用的条目,因为它突出显示按目录和文件类型区分条目。这似乎是这样的功能中一个非常被遗忘的部分。 (2认同)

Ale*_*bin 6

返回目录中的所有文件

斯威夫特3

import Foundation

let path = "<some path>"

let enumerator = FileManager.default.enumerator(atPath: path)

while let filename = enumerator?.nextObject() as? String {
        print(filename)
}
Run Code Online (Sandbox Code Playgroud)

  • 它不会进入子目录,也不会获取隐藏文件,也不会跟随符号链接 (2认同)

use*_*498 5

如果你得到了

"NSDirectoryEnumerator?没有名为'nextObject'的成员错误

while循环应该是:

while let element = enumerator?.nextObject() as? String {
  // do things with element
}
Run Code Online (Sandbox Code Playgroud)

它与可选链接有关

  • 为什么有些人不会得到这个错误? (2认同)

use*_*734 5

斯威夫特3

let fd = FileManager.default
fd.enumerator(atPath: "/Library/FileSystems")?.forEach({ (e) in
    if let e = e as? String, let url = URL(string: e) {
        print(url.pathExtension)
    }
})
Run Code Online (Sandbox Code Playgroud)


neo*_*eye 5

Swift3 +绝对网址

extension FileManager {
    func listFiles(path: String) -> [URL] {
        let baseurl: URL = URL(fileURLWithPath: path)
        var urls = [URL]()
        enumerator(atPath: path)?.forEach({ (e) in
            guard let s = e as? String else { return }
            let relativeURL = URL(fileURLWithPath: s, relativeTo: baseurl)
            let url = relativeURL.absoluteURL
            urls.append(url)
        })
        return urls
    }
}
Run Code Online (Sandbox Code Playgroud)

基于@ user3441734中的代码


小智 5

斯威夫特 3.0

返回传递的目录及其子目录中具有扩展名的所有文件

func extractAllFile(atPath path: String, withExtension fileExtension:String) -> [String] {
    let pathURL = NSURL(fileURLWithPath: path, isDirectory: true)
    var allFiles: [String] = []
    let fileManager = FileManager.default
    let pathString = path.replacingOccurrences(of: "file:", with: "")
    if let enumerator = fileManager.enumerator(atPath: pathString) {
        for file in enumerator {
            if #available(iOS 9.0, *) {
                if let path = NSURL(fileURLWithPath: file as! String, relativeTo: pathURL as URL).path, path.hasSuffix(".\(fileExtension)"){
                    let fileNameArray = (path as NSString).lastPathComponent.components(separatedBy: ".")
                    allFiles.append(fileNameArray.first!)
                }
            } else {
                // Fallback on earlier versions
                print("Not available, #available iOS 9.0 & above")
            }
        }
    }
    return allFiles
}
Run Code Online (Sandbox Code Playgroud)