Swift의 FileManager를 사용하여 폴더 및 하위 폴더의 파일을 반복합니다.
저는 Swift 프로그래밍에 익숙하지 않으며 폴더의 파일을 반복하려고합니다. 여기 에서 답을 살펴보고 Swift 구문으로 번역하려고 시도했지만 성공하지 못했습니다.
let fileManager = NSFileManager.defaultManager()
let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(folderPath)
for element in enumerator {
//do something
}
내가 얻는 오류는 다음과 같습니다.
Type 'NSDirectoryEnumerator' does not conform to protocol 'SequenceType'
내 목표는 기본 폴더에 포함 된 모든 하위 폴더와 파일을 살펴보고 특정 확장명을 가진 모든 파일을 찾아서 작업을 수행하는 것입니다.
사용 nextObject()
방법 enumerator
:
while let element = enumerator?.nextObject() as? String {
if element.hasSuffix("ext") { // checks the extension
}
}
요즘 (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)
}
pNre의 솔루션이 전혀 작동하지 않았습니다. while 루프는 아무것도받지 못했습니다. 그러나 나는 나를 위해 일하는이 솔루션을 발견했습니다 (Xcode 6 베타 6에서는 pNre가 위의 답변을 게시 한 이후로 상황이 변경되었을 수 있습니까?).
for url in enumerator!.allObjects {
print("\((url as! NSURL).path!)")
}
디렉토리 + 하위 디렉토리의 모든 파일을 반환합니다.
import Foundation
let path = "<some path>"
let enumerator = FileManager.default.enumerator(atPath: path)
while let filename = enumerator?.nextObject() as? String {
print(filename)
}
당신이 얻는 경우에
'NSDirectoryEnumerator?' 'nextObject' 라는 멤버가 없습니다. 오류
while 루프는 다음과 같아야합니다.
while let element = enumerator?.nextObject() as? String {
// do things with element
}
그것은 함께 할 수있는 뭔가가 선택 체인을
스위프트 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)
}
})
Swift3 + 절대 URL
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
}
}
@ user3441734의 코드를 기반으로 함
SWIFT 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
}
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 ....
}
}
이전 답변에서 내 2 센트 .. 더 신속하고 선택 사항 :
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")
}
}
}
Adding to vadian's response -- the Apple docs mention that Path-based URLs are simpler in some ways, however file reference URLs have the advantage that the reference remains valid if the file is moved or renamed while your app is running.
From the documentation for "Accessing Files and Directories":
"Path-based URLs are easier to manipulate, easier to debug, and are generally preferred by classes such as NSFileManager. An advantage of file reference URLs is that they are less fragile than path-based URLs while your app is running. If the user moves a file in the Finder, any path-based URLs that refer to the file immediately become invalid and must be updated to the new path. However, as long as the file moved to another location on the same disk, its unique ID does not change and any file reference URLs remain valid."
If you want to categorically check whether an element is a file or a subdirectory:
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
}
}
Recently struggled with this when handling an array of urls, whether they be a directory or not (eg. drag and drop). Ended up with this extension in swift 4, may be of use
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
}
}
Avoid reference URLs, while they do have some advantages as stated above, they eat system resources and if you’re enumerating a large filesystem (not that large actually) your app will hit a system wall quickly and get shutdown by macOS.
'Program Tip' 카테고리의 다른 글
3 열 레이아웃 HTML / CSS (0) | 2020.11.16 |
---|---|
Git은 추적 된 파일의 일부에 대한 로컬 변경 사항을 무시합니다. (0) | 2020.11.16 |
Xcode 6.0.1 명령 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc가 종료 코드 1과 함께 실패했습니다. (0) | 2020.11.16 |
Angular에서 사용자 지정 테마 팔레트를 어떻게 사용할 수 있습니까? (0) | 2020.11.16 |
bash의 백틱에 해당하는 cmd / powershell은 무엇입니까? (0) | 2020.11.16 |