FileManager 是 Swift 中的一个类,用于管理和操作文件系统。它提供了多种方法,可以对文件、目录、属性等进行创建、读取、写入、复制、移动和删除等操作。
FileManager 非常适合在应用中管理本地文件,例如保存用户数据、读取配置文件或缓存文件。
基本介绍
FileManager 是一个单例类,主要用于与文件系统进行交互。它提供了很多实用的静态方法来处理文件系统中的文件和目录。
FileManager 实际上有很多方法用于处理文件和目录,它可以轻松地进行文件系统操作。
let fileManager = FileManager.default
这里 FileManager.default 是获取 FileManager 的默认实例,可以用它来执行各种文件操作。
常见用途
1、获取文件路径:如应用的文档目录、缓存目录等。
2、检查文件是否存在。
3、创建、复制、移动、删除文件或目录。
4、读取文件的属性。
5、列出目录的内容。
常见方法
1、获取文件路径
可以使用 FileManager 获取沙盒目录中的各种路径,像是文档目录、缓存目录、临时目录等。
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let cachesURL = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
let tempURL = fileManager.temporaryDirectory
代码解析:
fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
urls(for:in:) 是 FileManager 的一个方法,用来查找指定的系统目录。
.documentDirectory:表示“文档”目录,也就是 Documents 文件夹。在 iOS 应用中,这个目录是专门用来存储用户可以访问的文档文件的。
.userDomainMask:表示在用户的主目录下查找文件夹,通常就是应用的沙盒区域(例如 ~/Documents)。
该方法返回一个包含 URL 的数组,因为可能存在多个匹配的路径(但通常在 iOS 上,Documents 目录只有一个)。
.first:
调用了 first 属性,意在从返回的 URL 数组中获取第一个 URL(通常也是唯一的一个)。
通过使用 first,可以直接得到 Documents 目录的 URL(如果存在),以避免直接操作数组的繁琐性。

2、创建目录
可以使用 createDirectory 方法在文件系统中创建目录。
let directoryURL = documentsURL.appendingPathComponent("MyFolder")
do {
try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil)
print("目录创建成功")
} catch {
print("创建目录失败: \(error)")
}
3、创建文件
let fileURL = documentsURL.appendingPathComponent("example.txt")
let contents = "Hello, World!".data(using: .utf8)
fileManager.createFile(atPath: fileURL.path, contents: contents, attributes: nil)
4、文件的存在性检查
使用 fileExists(atPath:) 方法可以检查文件是否存在。
let fileURL = documentsURL.appendingPathComponent("example.txt")
if fileManager.fileExists(atPath: fileURL.path) {
print("文件存在")
} else {
print("文件不存在")
}
5、复制文件
可以使用 copyItem(at:to:) 方法复制文件。
let sourceURL = documentsURL.appendingPathComponent("source.txt")
let destinationURL = documentsURL.appendingPathComponent("destination.txt")
do {
try fileManager.copyItem(at: sourceURL, to: destinationURL)
print("文件复制成功")
} catch {
print("复制文件失败: \(error)")
}
6、移动文件
moveItem(at:to:) 方法可以用来移动文件。
let sourceURL = documentsURL.appendingPathComponent("source.txt")
let destinationURL = documentsURL.appendingPathComponent("movedFile.txt")
do {
try fileManager.moveItem(at: sourceURL, to: destinationURL)
print("文件移动成功")
} catch {
print("移动文件失败: \(error)")
}
7、删除文件
使用 removeItem(at:) 方法删除文件。
let fileURL = documentsURL.appendingPathComponent("fileToDelete.txt")
do {
try fileManager.removeItem(at: fileURL)
print("文件删除成功")
} catch {
print("删除文件失败: \(error)")
}
8、读取文件内容
可以使用 contents(atPath:) 或 contentsOfDirectory(at:) 来读取文件的内容。
let fileURL = documentsURL.appendingPathComponent("example.txt")
if let fileData = fileManager.contents(atPath: fileURL.path) {
let content = String(data: fileData, encoding: .utf8)
print(content ?? "无法读取文件内容")
} else {
print("文件读取失败")
}
9、获取目录内容
使用 contentsOfDirectory(atPath:) 获取目录中的文件列表。
do {
let files = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil, options: [])
for file in files {
print(file.lastPathComponent)
}
} catch {
print("获取目录内容失败: \(error)")
}
10、获取文件属性
可以使用 attributesOfItem(atPath:) 方法获取文件的属性,如文件大小、修改时间等。
let fileURL = documentsURL.appendingPathComponent("example.txt")
do {
let attributes = try fileManager.attributesOfItem(atPath: fileURL.path)
if let fileSize = attributes[.size] as? NSNumber {
print("文件大小: \(fileSize.intValue) bytes")
}
} catch {
print("获取文件属性失败: \(error)")
}
11、检查路径是否为目录
使用 isDirectory(at:) 来判断一个路径是否是目录。
let fileURL = documentsURL.appendingPathComponent("example.txt")
var isDirectory: ObjCBool = false
if fileManager.fileExists(atPath: fileURL.path, isDirectory: &isDirectory) {
if isDirectory.boolValue {
print("是目录")
} else {
print("是文件")
}
} else {
print("路径不存在")
}
常用属性
1、temporaryDirectory
类型:URL
说明:返回一个指向应用程序沙盒中的临时目录的 URL。这个目录是操作系统为应用程序提供的临时文件存储位置,应用退出后这些文件可能会被删除。
let tempDirectory = FileManager.default.temporaryDirectory
2、homeDirectoryForCurrentUser
类型:URL
说明:返回当前用户的主目录。对于 macOS 或 iOS 设备,它指向当前用户的文件系统根目录(例如 /Users/username)。
let homeDirectory = FileManager.default.homeDirectoryForCurrentUser
3、documentDirectory
类型:URL
说明:返回一个指向应用程序沙盒中的文档目录的 URL。这个目录是用来存储应用程序需要持久化的数据文件的,通常用于存储用户数据,文件在应用重启时保持不变。
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
解释:需要通过 urls(for:in:) 方法来获取 documentDirectory 的路径,并指定目录类型 .userDomainMask(指向用户的目录),因为 FileManager 支持多个文件目录位置。
4、cachesDirectory
类型:URL
说明:返回一个指向应用程序沙盒中的缓存目录的 URL。这个目录用于存储可以被重新创建或下载的文件,文件系统中存储的数据可以在系统资源紧张时被删除。
let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first
5、applicationSupportDirectory
类型:URL
说明:返回一个指向应用程序沙盒中的支持目录的 URL。这个目录用于存储应用程序的配置文件和其他支持性数据,不应存储用户生成的数据。
let appSupportDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first
6、libraryDirectory
类型:URL
说明:返回一个指向应用程序沙盒中的库目录的 URL。这个目录通常用于存储应用程序的支持文件、配置文件以及其他由应用生成的文件。与 applicationSupportDirectory 类似,但有时用于特定的库文件。
let libraryDirectory = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first
7、developerDirectory
类型:URL
说明:仅在 macOS 上有效,指向 Xcode 的开发者目录。通常不直接与应用程序开发相关,除非是在开发工具链或其他与开发有关的文件。
let developerDirectory = FileManager.default.developerDirectory
8、downloadsDirectory(仅适用于 macOS)
类型:URL
说明:指向下载目录的 URL,通常是用户从浏览器或其他应用下载文件时的默认存储位置。
let downloadsDirectory = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first
9、sharedPublicDirectory(仅适用于 macOS)
类型:URL
说明:返回一个指向公共目录的 URL,这是多个应用共享的目录,用于存储公共文件,适用于 macOS 的多用户环境。
let sharedPublicDirectory = FileManager.default.sharedPublicDirectory
10、systemDirectory
类型:URL
说明:返回指向系统文件目录的 URL,通常用于 macOS。
let systemDirectory = FileManager.default.systemDirectory
11、trashDirectory
类型:URL
说明:返回当前用户的回收站目录的 URL,用于存放用户删除的文件。
let trashDirectory = FileManager.default.trashDirectory
示例:保存、读取和删除文件
let fileManager = FileManager.default
// 获取文件路径
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsURL.appendingPathComponent("example.txt")
// 保存数据到文件
let content = "Hello, World!"
do {
try content.write(to: fileURL, atomically: true, encoding: .utf8)
print("文件已保存")
} catch {
print("保存文件时出错: \(error)")
}
// 读取文件内容
do {
let fileContent = try String(contentsOf: fileURL, encoding: .utf8)
print("文件内容: \(fileContent)")
} catch {
print("读取文件时出错: \(error)")
}
// 删除文件
do {
try fileManager.removeItem(at: fileURL)
print("文件已删除")
} catch {
print("删除文件时出错: \(error)")
}
总结
FileManager 是一个非常强大的类,用于管理文件系统中的文件和目录。可以通过它执行诸如创建目录、复制文件、删除文件、检查文件存在性、获取文件属性等操作。在 iOS 和 macOS 开发中,FileManager 是处理文件的主要工具。
扩展知识
临时目录
当使用 URLSession.shared.downloadTask(with: url) 下载文件,常常用到临时目录temporaryDirectory。
let fileManager = FileManager.default
let destinationURL = fileManager.temporaryDirectory.appendingPathComponent("downloadedFile")
private let fileURL = URL(string: "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.zip")!
let task = URLSession.shared.downloadTask(with: fileURL) { localURL, response, error in
if let error = error {
print("下载失败: \(error)")
return
}
if let localURL = localURL,let response = response {
// 保存到永久路径
let fileManager = FileManager.default
let destinationURL = fileManager.temporaryDirectory.appendingPathComponent("downloadedFile")
do {
try fileManager.moveItem(at: localURL, to: destinationURL)
print("文件已保存到:\(destinationURL)")
} catch {
print("移动文件时出错:\(error)")
}
} else { return }
}
task.resume() // 启动下载任务
这个代码中downloadTask 方法的完成闭包返回的是一个 localURL,它是下载文件在本地临时存储路径的 URL。这里的 guard let localURL = localURL else { return } 是用来确保文件下载成功并且 localURL 被正确传递的。如果下载成功,localURL 就是一个指向临时文件存储位置的路径。
在Xcode模拟器中,localURL临时路径为:
1、第一次下载文件的临时文件路径:
file:///Users/fangjunyu/Library/Developer/Xcode/UserData/Previews/Simulator%20Devices/DE733730-2C79-48CC-A1DF-6B32D409600A/data/Containers/Data/Application/C50AF07E-1880-49AA-A808-52161CE4F851/tmp/CFNetworkDownload_WG4NvW.tmp
2、第二次下载文件的临时文件路径:
file:///Users/fangjunyu/Library/Developer/Xcode/UserData/Previews/Simulator%20Devices/DE733730-2C79-48CC-A1DF-6B32D409600A/data/Containers/Data/Application/99B4C01F-337D-47FA-BE68-377E3FABA060/tmp/CFNetworkDownload_BtiV5V.tmp
downloadTask 下载的文件会自动存放在系统的临时目录中,而这个临时目录由 iOS 或 macOS 自动管理(例如 /tmp 或其他类似路径)。这个路径是临时的,它由系统自动管理。它不属于应用的直接控制范围,因此,通常无法直接指定这个路径,而只能通过下载任务的回调函数的 localURL 来访问它。
临时目录 (temporaryDirectory)
temporaryDirectory 是一个系统提供的目录,应用运行时可以使用这个目录存储临时文件。
可以通过 fileManager.temporaryDirectory 来访问这个目录,它是一个相对稳定的位置,可以把文件移动到该目录来确保它不会被系统自动删除(但这不是永久存储的位置)。
为什么移动文件到 temporaryDirectory?
下载的文件是临时的:downloadTask 下载的文件是暂时的,且文件的命名和存储路径是由系统生成的,通常在应用退出或系统需要清理空间时,这些文件会被删除。
temporaryDirectory 是相对稳定的:使用 fileManager.temporaryDirectory.appendingPathComponent(“downloadedFile”) 生成路径时,它会为文件提供一个新的位置,虽然仍然是临时目录,但可以通过 temporaryDirectory 这个路径引用到自己的文件,而不需要直接使用系统自动生成的临时文件名。
为什么 temporaryDirectory 不等于 downloadTask 的临时路径?
downloadTask 使用系统的默认临时文件路径来存储下载文件。这个路径是由系统生成的,而且系统会在某些情况下删除文件。
temporaryDirectory 是用来为文件指定一个明确路径的目录,它允许临时文件指定名称,确保文件不被自动删除,可以自定义文件名和路径。
临时目录总结
downloadTask 下载的文件路径:是由系统生成的临时路径,可以通过回调中的 localURL 获取。
为什么需要 temporaryDirectory:temporaryDirectory 是一个稳定的临时目录位置,可以为文件指定一个自定义路径,而不是使用系统生成的默认路径。它保证一个统一的路径来引用文件。
区别:downloadTask 下载的文件是临时的,并且路径是系统生成的,而 temporaryDirectory 在系统的临时目录下保存并控制文件的路径(包括命名)。