Ich bin ziemlich neu in der Programmierung eines Swift und versuche, die Dateien in einem Ordner zu durchlaufen. Ich habe mir die Antwort hier angesehen und versucht, sie in die Swift-Syntax zu übersetzen, aber es gelang mir nicht.
let fileManager = NSFileManager.defaultManager()
let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(folderPath)
for element in enumerator {
//do something
}
Der Fehler, den ich bekomme, ist:
Type 'NSDirectoryEnumerator' does not conform to protocol 'SequenceType'
Mein Ziel ist es, alle im Hauptordner enthaltenen Unterordner und Dateien zu betrachten und alle Dateien mit einer bestimmten Erweiterung zu finden, um dann etwas mit ihnen zu tun.
swift
cocoa
nsfilemanager
Iacopo Boccalari
quelle
quelle
while
gegenüber der dichtenfor
Lösung bevorzugt wird. (Oh, ich sehe, ich habe die andere Lösung ohnehin schon ähnlich kommentiert - sowieso)enumerator(at:, includingPropertiesForKeys:, options:)
Berücksichtigen Sie bei der Verwendung , dass das Element tatsächlich eine URL und keine Zeichenfolge ist. Wenn Sie diesen Code verwenden, wird nichts zurückgegeben.while let element = enumerator?.nextObject() as? URL {...}
Heutzutage (Anfang 2017) wird dringend empfohlen, die - vielseitigere - URL-bezogene API zu verwenden
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) }
quelle
Ich konnte die Lösung von pNre überhaupt nicht zum Laufen bringen. Die while-Schleife hat einfach nie etwas erhalten. Ich bin jedoch auf diese Lösung gestoßen, die für mich funktioniert (in Xcode 6 Beta 6 haben sich die Dinge vielleicht geändert, seit pNre die obige Antwort veröffentlicht hat?):
for url in enumerator!.allObjects { print("\((url as! NSURL).path!)") }
quelle
Gibt alle Dateien in einem Verzeichnis + in Unterverzeichnissen zurück
import Foundation let path = "<some path>" let enumerator = FileManager.default.enumerator(atPath: path) while let filename = enumerator?.nextObject() as? String { print(filename) }
quelle
let path = "mydir"
, passiert nichts. Ich benutze schnelle 5.Swift3 + absolute URLs
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 } }
Basierend auf dem Code von @ user3441734
quelle
Swift 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) } })
quelle
Für den Fall, dass Sie die bekommen
Die while-Schleife sollte sein:
while let element = enumerator?.nextObject() as? String { // do things with element }
Es hat etwas mit optionaler Verkettung zu tun
quelle
SWIFT 3.0
Gibt alle Dateien mit der Erweiterung im übergebenen Verzeichnis und seinen Unterverzeichnissen zurück
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 }
quelle
meine zwei Cent aus früheren Antworten .. schneller und mit Optionen:
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") } } }
quelle
Aktualisierung für Swift 3:
let fileManager = FileManager() // let fileManager = NSFileManager.defaultManager() let en=fileManager.enumerator(atPath: the_path) // let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(folderPath) while let element = en?.nextObject() as? String { if element.hasSuffix("ext") { // do something with the_path/*.ext .... } }
quelle
Hinzufügen zur Antwort von vadian - In den Apple-Dokumenten wird erwähnt, dass pfadbasierte URLs in gewisser Weise einfacher sind. Dateireferenz-URLs haben jedoch den Vorteil, dass die Referenz gültig bleibt, wenn die Datei verschoben oder umbenannt wird, während Ihre App ausgeführt wird.
Aus der Dokumentation zu "Zugriff auf Dateien und Verzeichnisse":
"Pfadbasierte URLs sind einfacher zu bearbeiten, einfacher zu debuggen und werden im Allgemeinen von Klassen wie NSFileManager bevorzugt. Ein Vorteil von Dateireferenz-URLs besteht darin, dass sie weniger anfällig sind als pfadbasierte URLs, während Ihre App ausgeführt wird. Wenn der Benutzer Wenn eine Datei im Finder verschoben wird, werden alle pfadbasierten URLs, die auf die Datei verweisen, sofort ungültig und müssen auf den neuen Pfad aktualisiert werden. Solange die Datei jedoch an einen anderen Speicherort auf derselben Festplatte verschoben wird, wird ihre eindeutige ID nicht verwendet ändern und alle Dateireferenz-URLs bleiben gültig. "
https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/AccessingFilesandDirectories/AccessingFilesandDirectories.html
quelle
Wenn Sie kategorisch prüfen möchten, ob ein Element eine Datei oder ein Unterverzeichnis ist:
let enumerator = FileManager.default.enumerator(atPath: contentsPath); while let element = enumerator?.nextObject() as? String { if(enumerator?.fileAttributes?[FileAttributeKey.type] as! FileAttributeType == FileAttributeType.typeRegular){ //this is a file } else if(enumerator?.fileAttributes?[FileAttributeKey.type] as! FileAttributeType == FileAttributeType.typeDirectory){ //this is a sub-directory } }
quelle
Vor kurzem hatte ich Probleme damit, wenn ich ein Array von URLs behandelte, unabhängig davon, ob es sich um ein Verzeichnis handelt oder nicht (z. B. Drag & Drop). Endete mit dieser Erweiterung in Swift 4, kann von Nutzen sein
extension Sequence where Iterator.Element == URL { var handleDir: [URL] { var files: [URL] = [] self.forEach { u in guard u.hasDirectoryPath else { return files.append(u.resolvingSymlinksInPath()) } guard let dir = FileManager.default.enumerator(at: u.resolvingSymlinksInPath(), includingPropertiesForKeys: nil) else { return } for case let url as URL in dir { files.append(url.resolvingSymlinksInPath()) } } return files } }
quelle
Vermeiden Sie Referenz-URLs, obwohl sie, wie oben angegeben, einige Vorteile haben. Sie verbrauchen Systemressourcen. Wenn Sie ein großes Dateisystem aufzählen (das eigentlich nicht so groß ist), stößt Ihre App schnell an eine Systemwand und wird von macOS heruntergefahren.
quelle