문서 폴더의 파일 목록 가져 오기


124

문서 폴더에서 파일 이름을 가져 오는 코드에 어떤 문제가 있습니까?

func listFilesFromDocumentsFolder() -> [NSString]?{
    var theError = NSErrorPointer()
    let dirs = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String]
    if dirs != nil {
        let dir = dirs![0] as NSString
        let fileList = NSFileManager.defaultManager().contentsOfDirectoryAtPath(dir, error: theError) as [NSString]
        return fileList
    }else{
        return nil
    }
}

문서를 올바르게 읽었다 고 생각했고 문서 폴더에있는 내용이 확실하지만 "fileList"에 아무것도 표시되지 않습니까? "dir"은 폴더 경로를 표시합니다.


문서 디렉토리에있는 파일의 이름을 표시 하시겠습니까 아니면 폴더에있는 파일도 표시 하시겠습니까?
Adeel Ur Rehman 2014

첫째, 문서 폴더 자체에있는 파일 만!
pawi dec

방금 코드를 실행했는데 예상대로 작동했습니다. 내 문서 디렉토리에있는 목록을 받았습니다. 귀하의 질문을 오해합니까?
jwlaughton

이상한? 또한 특정 파일이 있음을 알려주는 ".fileExistsAtPath (path)"를 사용했습니다. 그러나 "fileList"에는 아무것도 나타나지 않습니다!?
pawi dec

내 목록에는 디렉토리와 파일이 모두 포함되어 있습니다.
jwlaughton

답변:


111

이 솔루션은 Swift 4 (Xcode 9.2) 및 Swift 5 (Xcode 10.2.1+)에서도 작동합니다.

let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
do {
    let fileURLs = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
    // process files
} catch {
    print("Error while enumerating files \(documentsURL.path): \(error.localizedDescription)")
}

다음은 결과에 숨겨진 파일을 건너 뛰거나 포함 할 수있는 재사용 가능한 FileManager 확장입니다.

import Foundation

extension FileManager {
    func urls(for directory: FileManager.SearchPathDirectory, skipsHiddenFiles: Bool = true ) -> [URL]? {
        let documentsURL = urls(for: directory, in: .userDomainMask)[0]
        let fileURLs = try? contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil, options: skipsHiddenFiles ? .skipsHiddenFiles : [] )
        return fileURLs
    }
}

// Usage
print(FileManager.default.urls(for: .documentDirectory) ?? "none")

숨겨진 파일을 제외하려면 어떻게해야합니까?
BasedMusa

251

스위프트 5

// Get the document directory url
let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

do {
    // Get the directory contents urls (including subfolders urls)
    let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil)
    print(directoryContents)

    // if you want to filter the directory contents you can do like this:
    let mp3Files = directoryContents.filter{ $0.pathExtension == "mp3" }
    print("mp3 urls:",mp3Files)
    let mp3FileNames = mp3Files.map{ $0.deletingPathExtension().lastPathComponent }
    print("mp3 list:", mp3FileNames)

} catch {
    print(error)
}

1
나만큼 부주의 한 사람들을 위해. 호출 : FileManager.default.contentsOfDirectory (atPath : <# T ## String #>)는 Swift 3.0에서 알 수없는 이유로 제대로 작동하지 않을 수 있습니다. 여기에서 위에 주어진 것을 사용하십시오.
Michael Shang 2011

iCloud Drive 디렉터리에서 실행하면 기기에 다운로드 된 항목 만 반환됩니다. 먼저 다운로드하지 않고 모든 항목의 URL을 가져올 수있는 방법이 있습니까?
mralexhay

@mralexhay 그것은 다운로드되지 않은 항목도 나에게 보여줍니다. 파일 이름에 점 .접두사와 .cloud접미사 가 표시되어야합니다 . 시도 let icloudFiles = directoryContents.filter{ $0.pathExtension == "icloud" }다운로드되지 않은 파일을 표시해야합니다 그것을
레오 버스들이시길

1
@LeoDabus 답장을 보내 주셔서 감사합니다. "."가 앞에 붙는다는 사실을 몰랐습니다. "iCloud"접미사가있는 줄 알았어요. 숨겨진 파일을 반환하지 않는다는 것을 깨달았습니다. 보이지 않는 것은 당연합니다! 다시 한 번 감사드립니다.
mralexhay

17

SWIFT 3의 더 짧은 구문

func listFilesFromDocumentsFolder() -> [String]?
{
    let fileMngr = FileManager.default;

    // Full path to documents directory
    let docs = fileMngr.urls(for: .documentDirectory, in: .userDomainMask)[0].path

    // List all contents of directory and return as [String] OR nil if failed
    return try? fileMngr.contentsOfDirectory(atPath:docs)
}

사용 예 :

override func viewDidLoad()
{
    print(listFilesFromDocumentsFolder())
}

iOS 10.2가 설치된 iPhone 7 및 iOS 9.3이 설치된 iPad 용 xCode 8.2.3에서 테스트되었습니다.


6

Apple은 다음에 대해 설명합니다 NSSearchPathForDirectoriesInDomains(_:_:_:).

선호하는 형식 인 FileManager메소드 urls(for:in:)url(for:in:appropriateFor:create:)반환 URL 사용을 고려해야 합니다.


Swift 5 FileManager에는 contentsOfDirectory(at:includingPropertiesForKeys:options:). contentsOfDirectory(at:includingPropertiesForKeys:options:)다음과 같은 선언이 있습니다.

지정된 디렉토리의 단순 검색을 수행하고 포함 된 항목에 대한 URL을 리턴합니다.

func contentsOfDirectory(at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: FileManager.DirectoryEnumerationOptions = []) throws -> [URL]

따라서 문서 디렉토리에 포함 된 파일의 URL을 검색하려면 FileManagerurls(for:in:)contentsOfDirectory(at:includingPropertiesForKeys:options:)메소드를 사용하는 다음 코드 스 니펫을 사용할 수 있습니다 .

guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }

do {
    let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil, options: [])

    // Print the urls of the files contained in the documents directory
    print(directoryContents)
} catch {
    print("Could not search for urls of files in documents directory: \(error)")
}

예를 들어 UIViewController아래 구현은 App Bundle의 파일을 문서 디렉토리에 저장하는 방법과 문서 디렉토리에 저장된 파일의 URL을 가져 오는 방법을 보여줍니다.

import UIKit

class ViewController: UIViewController {

    @IBAction func copyFile(_ sender: UIButton) {
        // Get file url
        guard let fileUrl = Bundle.main.url(forResource: "Movie", withExtension: "mov") else { return }

        // Create a destination url in document directory for file
        guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
        let documentDirectoryFileUrl = documentsDirectory.appendingPathComponent("Movie.mov")

        // Copy file to document directory
        if !FileManager.default.fileExists(atPath: documentDirectoryFileUrl.path) {
            do {
                try FileManager.default.copyItem(at: fileUrl, to: documentDirectoryFileUrl)
                print("Copy item succeeded")
            } catch {
                print("Could not copy file: \(error)")
            }
        }
    }

    @IBAction func displayUrls(_ sender: UIButton) {
        guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }

        do {
            let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsDirectory, includingPropertiesForKeys: nil, options: [])

            // Print the urls of the files contained in the documents directory
            print(directoryContents) // may print [] or [file:///private/var/mobile/Containers/Data/Application/.../Documents/Movie.mov]
        } catch {
            print("Could not search for urls of files in documents directory: \(error)")
        }
    }

}

5

이 코드는 내 문서 디렉토리의 모든 디렉토리와 파일을 인쇄합니다.

함수의 일부 수정 :

func listFilesFromDocumentsFolder() -> [String]
{
    let dirs = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true)
    if dirs != [] {
        let dir = dirs[0]
        let fileList = try! FileManager.default.contentsOfDirectory(atPath: dir)
        return fileList
    }else{
        let fileList = [""]
        return fileList
    }
}

호출되는 사람 :

    let fileManager:FileManager = FileManager.default
    let fileList = listFilesFromDocumentsFolder()

    let count = fileList.count

    for i in 0..<count
    {
        if fileManager.fileExists(atPath: fileList[i]) != true
        {
            print("File is \(fileList[i])")
        }
    }

4

Swift 2.0 호환성

func listWithFilter () {

    let fileManager = NSFileManager.defaultManager()
           // We need just to get the documents folder url
    let documentsUrl = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL

    do {
    // if you want to filter the directory contents you can do like this:
    if let directoryUrls = try? NSFileManager.defaultManager().contentsOfDirectoryAtURL(documentsUrl, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions.SkipsSubdirectoryDescendants) {
        print(directoryUrls)
       ........
        }

    }

}

또는

 func listFiles() -> [String] {

    var theError = NSErrorPointer()
    let dirs = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String]
    if dirs != nil {
        let dir = dirs![0]
        do {
        let fileList = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(dir)
        return fileList as [String]
        }catch {

        }

    }else{
        let fileList = [""]
        return fileList
    }
    let fileList = [""]
    return fileList

}

0

간단하고 역동적 인 솔루션 (Swift 5) :

extension FileManager {

  class func directoryUrl() -> URL? {
      let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
      return paths.first
  }

  class func allRecordedData() -> [URL]? {
     if let documentsUrl = FileManager.directoryUrl() {
        do {
            let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil)
            return directoryContents.filter{ $0.pathExtension == "m4a" }
        } catch {
            return nil
        }
     }
     return nil
  }}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.