【问题标题】:Getting list of files in documents folder获取文档文件夹中的文件列表
【发布时间】:2015-02-27 13:27:20
【问题描述】:

获取文件夹中文件名的代码有什么问题?

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”显示文件夹的路径。

【问题讨论】:

  • 您想显示文档目录中的文件名还是文件夹中的文件名?
  • 首先,只有文件夹本身的文件!
  • 我刚刚运行了您的代码,它按预期工作。我得到了我的文档目录中的内容列表。我们误解了您的问题吗?
  • 奇怪?我还使用了“.fileExistsAtPath(path)”,它告诉我存在一个特定的文件。但是“fileList”中什么也没有出现!?
  • 我的列表包括目录和文件。

标签: ios swift


【解决方案1】:

斯威夫特 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)
}

【讨论】:

  • 对于像我这样粗心的人。请注意,调用: FileManager.default.contentsOfDirectory(atPath: ) 在 Swift 3.0 中可能由于未知原因无法正常工作。使用上面给出的一个。
  • 如果我在 iCloud Drive 目录上运行它,它只会返回已下载到设备的项目 - 有没有办法在不先下载它们的情况下获取所有项目的 URL?
  • @mralexhay 它向我展示了它,即使是未下载的项目。它应该在文件名中显示一个点. 前缀和一个.cloud 后缀。试试let icloudFiles = directoryContents.filter{ $0.pathExtension == "icloud" } 应该会显示没有下载的文件
  • @LeoDabus 感谢您的回复 - 我没有意识到它会添加“。”,我以为它只有“iCloud”后缀。我意识到我没有返回隐藏文件 - 难怪他们没有显示!再次感谢。
【解决方案2】:

此代码打印出我的文档目录中的所有目录和文件:

对您的功能进行一些修改:

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

【讨论】:

    【解决方案3】:

    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
    
    }
    

    【讨论】:

      【解决方案4】:

      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())
      }
      

      在 xCode 8.2.3 上测试,适用于带有 iOS 10.2 的 iPhone 7 和带有 iOS 9.3 的 iPad

      【讨论】:

        【解决方案5】:

        苹果声明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,您可以使用以下代码sn -p 使用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 实现显示了如何将文件从应用程序包保存到文档目录以及如何获取保存在文档目录中的文件的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)")
                }
            }
        
        }
        

        【讨论】:

          【解决方案6】:

          此解决方案适用于 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")
          

          【讨论】:

          • 如何排除隐藏文件?
          • 默认已经排除了。如果想包含这样的调用函数:FileManager.default.urls(for: .documentDirectory, skipsHiddenFiles: false)
          【解决方案7】:

          简单而动态的解决方案(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
            }}
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-06-23
            • 1970-01-01
            • 2011-01-15
            • 2015-09-08
            • 2017-02-25
            • 2015-04-06
            • 1970-01-01
            相关资源
            最近更新 更多