获取文档文件夹中的文件列表

获取文档文件夹中的文件名的代码出了什么问题?

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

175547 次浏览

Swift 5

do {
// Get the document directory url
let documentDirectory = try FileManager.default.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: true
)
print("documentDirectory", documentDirectory.path)
// Get the directory contents urls (including subfolders urls)
let directoryContents = try FileManager.default.contentsOfDirectory(
at: documentDirectory,
includingPropertiesForKeys: nil
)
print("directoryContents:", directoryContents.map { $0.localizedName ?? $0.lastPathComponent })
for url in directoryContents {
print(url.localizedName ?? url.lastPathComponent)
}
    

// if you would like to hide the file extension
for var url in directoryContents {
url.hasHiddenExtension = true
}
for url in directoryContents {
print(url.localizedName ?? url.lastPathComponent)
}


// if you want to get all mp3 files located at the documents directory:
let mp3s = directoryContents.filter(\.isMP3).map { $0.localizedName ?? $0.lastPathComponent }
print("mp3s:", mp3s)
    

} catch {
print(error)
}

您需要将这些扩展添加到项目中

extension URL {
var typeIdentifier: String? { (try? resourceValues(forKeys: [.typeIdentifierKey]))?.typeIdentifier }
var isMP3: Bool { typeIdentifier == "public.mp3" }
var localizedName: String? { (try? resourceValues(forKeys: [.localizedNameKey]))?.localizedName }
var hasHiddenExtension: Bool {
get { (try? resourceValues(forKeys: [.hasHiddenExtensionKey]))?.hasHiddenExtension == true }
set {
var resourceValues = URLResourceValues()
resourceValues.hasHiddenExtension = newValue
try? setResourceValues(resourceValues)
}
}
}

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

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

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

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


}

SWIFT3的简短语法

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

在 xCode8.2.3上对 iOS10.2版的 iPhone7和 iOS9.3版的 iPad 进行了测试

苹果对 NSSearchPathForDirectoriesInDomains(_:_:_:)表示:

您应该考虑使用返回 URL 的 FileManager方法 urls(for:in:)url(for:in:appropriateFor:create:),这是首选的格式。


在 Swift 5中,FileManager有一个名为 contentsOfDirectory(at:includingPropertiesForKeys:options:)的方法:

对指定的目录执行浅层搜索并返回所包含项的 URL。

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

因此,为了检索 document 目录中包含的文件的 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 保存到 document 目录,以及如何获取保存在 document 目录中的文件的 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)")
}
}


}

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

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