FileManager 的简介 #
FileManager
是 iOS 和 macOS 开发中提供的一个强大的类,用于管理文件系统的操作。它提供了对文件和文件夹进行创建、删除、移动、复制以及检索其属性等多种功能的接口。
FileManager
是 Foundation
框架的一部分,是 用户文件系统交互的核心工具。
1. FileManager 的体系结构 #
FileManager
由以下几个部分组成:
模块 | 功能描述 |
---|---|
文件操作功能 | 创建、删除、移动、复制文件和目录。 |
文件路径解析 | 检索、拼接和解析文件路径,例如获取用户的文档目录或临时目录。 |
文件属性管理 | 获取文件属性,例如大小、创建时间、权限等。 |
文件存在检查 | 检查文件或文件夹是否存在。 |
枚举和搜索 | 枚举目录内容,递归浏览文件系统内容,或者根据条件搜索文件和文件夹。 |
文件权限 | 检查权限信息,以及管理可读、可写、可执行属性。 |
关键方法和属性 #
以下是 FileManager
的几个核心方法和属性:
以下是对 FileManager
的接口按功能分类的详细整理,包括方法名称以及对应的中文说明。分类基于 FileManager
的主要功能模块,包括文件操作、目录操作、文件系统信息、枚举和遍历操作等。
1. 文件操作
- 创建、删除、复制、移动文件及文件夹的基础管理。
2. 目录操作
- 创建文件夹、列举内容、获取子路径等。
3. 文件检查
- 检测文件是否存在,以及文件基本操作权限。
4. 文件属性
- 获取文件的大小、日期、权限等属性,或者设置某些属性。
5. 沙盒路径
- 获取用户目录、文档目录、缓存目录、临时路径等。
6. 数据写入与读取
- 管理文件的内容。
7. 遍历和枚举
- 遍历文件与子目录,递归或非递归模型支持。
1. 文件操作接口 #
方法名称 | 中文说明 |
---|---|
createFile(atPath:contents:attributes:) | 创建文件并写入数据。可以指定文件的路径、内容和属性。 |
removeItem(at:) | 删除指定路径的文件或文件夹。 |
copyItem(at:to:) | 复制文件或文件夹到目标路径。 |
moveItem(at:to:) | 移动或重命名文件或文件夹。 |
linkItem(at:to:) | 创建指定路径的硬链接。 |
contents(atPath:) | 读取文件的二进制数据内容。 |
contentsEqual(atPath:andPath:) | 比较两个文件是否完全相同。 |
replaceItem(at:withItemAt:backupItemName:options:) | 替换文件,可以选择备份原来的文件并指定备份文件的名称。 |
2. 目录操作接口 #
方法名称 | 中文说明 |
---|---|
createDirectory(at:withIntermediateDirectories:attributes:) | 创建一个新的目录,可以选择创建中间缺少的目录。 |
contentsOfDirectory(at:includingPropertiesForKeys:options:) | 获取指定目录中内容(如文件和子目录),包含属性信息。 |
subpathsOfDirectory(atPath:) | 获取指定路径的所有子路径(递归)。 |
enumerator(at:includingPropertiesForKeys:options:errorHandler:) | 枚举目录内容,包括文件和子目录。 |
changeCurrentDirectoryPath(_: String) | 更改当前工作目录路径。 |
displayName(atPath:) | 返回指定路径的友好显示名称。 |
3. 文件检查和验证接口 #
方法名称 | 中文说明 |
---|---|
fileExists(atPath:) | 检查指定的路径是否存在文件或目录。 |
isReadableFile(atPath:) | 检查路径是否可读取。 |
isWritableFile(atPath:) | 检查路径是否可写入。 |
isExecutableFile(atPath:) | 检查路径是否可执行。 |
isDeletableFile(atPath:) | 检查路径是否可以删除。 |
4. 文件系统属性接口 #
方法名称 | 中文说明 |
---|---|
attributesOfItem(atPath:) | 获取指定路径的文件或目录属性(如大小、创建时间)。 |
attributesOfFileSystem(forPath:) | 获取指定文件系统的属性(如可用空间、文件系统类型)。 |
setAttributes(_:ofItemAtPath:) | 设置文件或目录的属性,例如修改权限或修改时间戳。 |
5. 常见的沙盒和目录路径接口 #
方法名称 | 中文说明 |
---|---|
urls(for:in:) | 获取指定目录(如文档目录、缓存目录)的 URL。 |
temporaryDirectory | 获取系统的临时目录路径。 |
homeDirectoryForCurrentUser | 获取当前用户的主目录路径(仅 macOS 支持)。 |
homeDirectoryForGuest() | 获取访客用户的主目录路径(仅 macOS 支持)。 |
currentDirectoryPath | 获取或更改当前工作目录路径。 |
6. 数据读取与写入接口 #
方法名称 | 中文说明 |
---|---|
contents(atPath:) | 从文件路径读取内容并返回 Data 类型的二进制数据。 |
createFile(atPath:contents:attributes:) | 在指定路径上创建文件并写入内容。 |
removeItem(at:) | 删除文件或目录。 |
7. 目录遍历和枚举接口 #
方法名称 | 中文说明 |
---|---|
contentsOfDirectory(atPath:) | 返回指定路径的文件和子目录,不递归。 |
subpathsOfDirectory(atPath:) | 获取指定目录中所有内容(递归,包括文件夹和文件)。 |
enumerator(at:includingPropertiesForKeys:options:errorHandler:) | 创建目录枚举器,递归遍历目录中的文件和子目录。 |
8. 符号链接和硬链接操作接口 #
方法名称 | 中文说明 |
---|---|
linkItem(at:to:) | 在指定路径创建硬链接。 |
destinationOfSymbolicLink(atPath:) | 返回符号链接指向的真实路径(读取符号链接的目标路径)。 |
9. 数据迁移与备份接口 #
方法名称 | 中文说明 |
---|---|
replaceItem(at:withItemAt:backupItemName:options:) | 替换指定路径的文件,并可选择为原文件创建备份。 |
10. iCloud 文件操作接口 #
方法名称 | 中文说明 |
---|---|
url(forUbiquityContainerIdentifier:) | 获取 iCloud 容器目录的 URL(如果启用了 iCloud)。 |
isUbiquitousItem(at:) | 检查是否是 iCloud 文件。 |
11. 可用 iOS/macOS 的属性与共享组接口 #
方法名称 | 中文说明 |
---|---|
containerURL(forSecurityApplicationGroupIdentifier:) | 获取 App Group 共享目录,用于跨应用共享文件。 |
注意事项 #
以下为 FileManager
使用中的开发者常见注意点:
沙盒环境限制:
- iOS 应用运行在沙盒环境下,开发者只能访问自己应用的沙盒目录,比如
Documents
、Library
、Caches
等。 - 无法访问其他应用的目录或系统级目录。
- iOS 应用运行在沙盒环境下,开发者只能访问自己应用的沙盒目录,比如
文件操作权限:
- 在创建目录或文件时,需要检查操作权限是否满足,尤其在 macOS 上,如果涉及全局目录(例如
/Library
),需要管理员权限。
- 在创建目录或文件时,需要检查操作权限是否满足,尤其在 macOS 上,如果涉及全局目录(例如
错误处理:
- 几乎所有
FileManager
方法都可能抛出错误(如路径不存在、权限问题等),因此建议在操作文件时使用do-catch
语句来捕获错误。
- 几乎所有
数据安全性:
- 在存储敏感数据时,应确保文件和路径具备适当的权限控制(如
NSFileProtectionComplete
)。
- 在存储敏感数据时,应确保文件和路径具备适当的权限控制(如
跨平台适用性:
- 部分方法(例如
homeDirectoryForCurrentUser
和isUbiquitousItem(at:)
)仅适用于 macOS 或在启用了特定功能(如 iCloud)后才可用。
- 部分方法(例如
2. 使用 FileManager 的步骤 #
2.1 获取 FileManager 的共享实例 #
FileManager
是一个共享实例类,通过其 default
属性可以获取实例。
let fileManager = FileManager.default
通过此实例可以执行各种文件操作。
2.2 获取常见的沙盒路径 #
iOS 和 macOS 应用运行在一个 沙盒环境 中,无法直接访问系统文件。常见的沙盒目录包括:
目录类型 | 描述 |
---|---|
Documents | 用户可见的数据目录,用于持久化保存用户文件。 |
Caches | 用于存储缓存文件,可被系统随时清理。 |
Temporary | 临时目录,系统可能会随时清理。用于存储临时文件。 |
示例代码:获取常见目录 #
let fileManager = FileManager.default
// 获取文档目录路径
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
print("Documents Directory: \(documentsDirectory)")
}
// 获取缓存目录路径
if let cachesDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first {
print("Caches Directory: \(cachesDirectory)")
}
// 获取临时目录路径
let tempDirectory = fileManager.temporaryDirectory
print("Temporary Directory: \(tempDirectory)")
2.3 创建文件夹 #
示例代码: #
let fileManager = FileManager.default
// 创建自定义文件夹(路径为沙盒内 Documents 文件夹下)
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let newFolderURL = documentsDirectory.appendingPathComponent("NewFolder")
do {
try fileManager.createDirectory(at: newFolderURL, withIntermediateDirectories: true, attributes: nil)
print("Folder created at: \(newFolderURL)")
} catch {
print("Failed to create folder: \(error.localizedDescription)")
}
}
2.4 检查文件是否存在 #
示例代码: #
let filePath = "/path/to/your/file.txt"
if fileManager.fileExists(atPath: filePath) {
print("File exists.")
} else {
print("File does not exist.")
}
2.5 文件的存储与读取 #
1. 写入文本文件 #
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = documentsDirectory.appendingPathComponent("example.txt")
let data = "Hello, FileManager!".data(using: .utf8)
// 创建文件
fileManager.createFile(atPath: fileURL.path, contents: data, attributes: nil)
print("File created: \(fileURL)")
}
2. 读取文件数据 #
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = documentsDirectory.appendingPathComponent("example.txt")
if let fileData = fileManager.contents(atPath: fileURL.path),
let fileContent = String(data: fileData, encoding: .utf8) {
print("File content: \(fileContent)")
}
}
2.6 移动文件或重命名 #
示例代码: #
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let sourceURL = documentsDirectory.appendingPathComponent("example.txt")
let destinationURL = documentsDirectory.appendingPathComponent("renamed_example.txt")
do {
try fileManager.moveItem(at: sourceURL, to: destinationURL)
print("File moved/renamed to: \(destinationURL)")
} catch {
print("Failed to move file: \(error.localizedDescription)")
}
}
2.7 删除文件或文件夹 #
示例代码: #
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = documentsDirectory.appendingPathComponent("example.txt")
do {
try fileManager.removeItem(at: fileURL)
print("File deleted: \(fileURL)")
} catch {
print("Failed to delete file: \(error.localizedDescription)")
}
}
2.8 获取文件属性 #
你可以通过 attributesOfItem(atPath:)
方法检索文件的详细属性(如创建时间、文件大小等)。
示例代码: #
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = documentsDirectory.appendingPathComponent("example.txt")
do {
let attributes = try fileManager.attributesOfItem(atPath: fileURL.path)
print("File attributes: \(attributes)")
if let fileSize = attributes[.size] as? Int64 {
print("File size: \(fileSize) bytes")
}
} catch {
print("Failed to get file attributes: \(error.localizedDescription)")
}
}
3. FileManager 使用注意事项 #
沙盒环境
- iOS 应用只能访问自己的沙盒,不能直接访问系统的文件。
- 除非使用 File Provider 等扩展访问外部文件。
权限管理
- 对于隐私敏感文件(如照片、麦克风等数据的存储和访问),需要填写
Info.plist
并请求用户权限。
- 对于隐私敏感文件(如照片、麦克风等数据的存储和访问),需要填写
异常处理
- 几乎所有
FileManager
操作都可能导致错误,例如路径不存在、权限不足等。建议通过do-catch
处理所有异常。
- 几乎所有
临时文件管理
- 存储临时数据时,使用
temporaryDirectory
。系统会自动清理,但需要确保在不用时删除临时文件。
- 存储临时数据时,使用
4. 应用场景 #
- 存储用户文档,例如笔记、文本文件、图片。
- 缓存网络下载内容到沙盒的
Caches
中。 - 临时生成文件,在特定任务完成后移除它们。
- 读取和解析日志文件或配置文件。
通过 FileManager
,你可以轻松管理应用程序中的文件和目录操作。
FileManager.SearchPathDomainMask
是一个枚举类型,定义了文件系统的域(Domain)范围,用于在检索目录路径时指定特定的作用域,例如用户目录、系统目录等。这些选项在调用 FileManager
的方法(如 urls(for:in:)
或 NSHomeDirectory()
)时会用到。
它主要与 FileManager.SearchPathDirectory
一起使用,用于指定调用的目录位置(例如:文档目录、缓存目录),并限定查找的作用域(域对象)。
SearchPathDomainMask
的选项
#
以下是 SearchPathDomainMask
的可用值及其含义:
值 | 说明 |
---|---|
.userDomainMask | 用户域,表示当前用户特定的沙盒域,例如应用程序的文档、缓存或日志文件。这是 iOS 应用程序中最常用的域。 |
.localDomainMask | 本地域,包含对所有用户可见的资源。它通常表示存放在共享位置的资源目录,例如 /Library/Application Support 。 |
.networkDomainMask | 网络域,指的是基于网络的共享目录,例如网络挂载的卷。这一选项设计用于 macOS 平台,在 iOS 上很少使用。 |
.systemDomainMask | 系统域,代表操作系统的系统级目录,例如 /System/Library 。普通应用无权限访问此域。 |
.allDomainsMask | 所有域,包括上述所有域 |
SearchPathDomainMask
常和 urls(for:in:)
或 path(for:in:)
方法一起使用。
1. .userDomainMask
#
沙盒文件系统。
用途: 访问属于当前用户的文件目录(文档、缓存、临时文件等)。
示例:
if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { print("Documents Directory: \(documentsDirectory)") }
urls(for:in:)
返回用户在沙盒中的文件夹,适用于 iOS 应用程序,这也是当前绝大部分情况下使用的域。
2. .localDomainMask
#
- 多用户共享目录。
- 用途: 本地目录,可供所有用户访问的共享文件资源。
- 示例(macOS 平台):
if let localLibraryDirectory = FileManager.default.urls(for: .libraryDirectory, in: .localDomainMask).first { print("Local Library Directory: \(localLibraryDirectory)") }
- 输出路径示例:
/Library
3. .networkDomainMask
#
- 基于网络的共享目录。
- 用途: 检索网络挂载的共享卷(macOS 上用于访问网络文件系统)。
- 示例(macOS 中):
if let networkCacheDirectory = FileManager.default.urls(for: .cachesDirectory, in: .networkDomainMask).first { print("Network Cache Directory: \(networkCacheDirectory)") }
- 输出路径示例:
/Network/Library/Caches
4. .systemDomainMask
#
- 系统资源目录。
- 用途: 表示系统级别不可修改的目录,只读访问(如系统库文件)。在应用程序沙盒中不可用。
- 示例(macOS 中):
if let systemLibraryDirectory = FileManager.default.urls(for: .libraryDirectory, in: .systemDomainMask).first { print("System Library Directory: \(systemLibraryDirectory)") }
- 输出路径示例:
/System/Library
5. .allDomainsMask
#
结合所有域。
用途: 获取所有域(用户、本地、网络、系统)下的目标目录。对于 iOS 应用而言通常不使用,因为沙盒限制无法访问其他域。
示例:
let allDomains = FileManager.default.urls(for: .documentDirectory, in: .allDomainsMask) print("Directories in All Domains: \(allDomains)")
注意事项 #
iOS 的沙盒限制:
- 在 iOS 上,应用程序只能访问
.userDomainMask
相关的目录(因为沙盒限制),无法访问.localDomainMask
、.networkDomainMask
和.systemDomainMask
。 - 常用沙盒目录包括:
- 文档目录:
documentDirectory
- 缓存目录:
cachesDirectory
- 临时目录:
temporaryDirectory
- 文档目录:
- 在 iOS 上,应用程序只能访问
macOS 支持更多域:
- 在 macOS 上,
FileManager.SearchPathDomainMask
的其他域(如.localDomainMask
和.networkDomainMask
)更加常用,因为 macOS 上的文件系统没有 iOS 那样的沙盒限制。 - Apple 的目录结构:
/Users/username/...
(用户域)/Library/...
(本地域)/System/...
(系统域)/Network/...
(网络域)
- 在 macOS 上,
指定多个域:
- 如果你需要操作多个域,可以通过按位或 (
|
) 的方式组合多个域。 - 示例:
let domains: FileManager.SearchPathDomainMask = [.userDomainMask, .localDomainMask]
- 如果你需要操作多个域,可以通过按位或 (
总结 #
.userDomainMask
(用户域):沙盒范围,常用于 iOS。.localDomainMask
(本地域):共享资源目录,常用于 macOS。.networkDomainMask
(网络域):访问网络挂载资源,macOS 可用。.systemDomainMask
(系统域):仅限操作系统使用,普通 App 无法访问。.allDomainsMask
:包含了上述所有域。
在实践中:
- 在开发 iOS 应用程序 时,主要使用
.userDomainMask
。 - 在 macOS 开发 或涉及更多文件系统操作时,可以使用
.localDomainMask
和.systemDomainMask
扩展功能。
实用场景:结合 SearchPathDirectory #
FileManager.SearchPathDomainMask
通常和 FileManager.SearchPathDirectory
结合使用,用于定位具体目录中需要操作的文件。
以下枚举提供了多种特定目录类型:
常用 SearchPathDirectory | 描述 |
---|---|
.documentDirectory | 用户文档目录,数据存储在应用内 Documents 目录中。 |
.cachesDirectory | 缓存目录,可存放临时文件,系统会清理。 |
.libraryDirectory | 应用的库目录,用于存放指定的支持文件。 |
.tmpDirectory | 临时目录,存储的内容会在系统重启后被清除。 |
示例代码 #
let fileManager = FileManager.default
// 获取沙盒中文档目录
if let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
print("Documents Directory (User Domain): \(documentsDirectory)")
}
// 获取沙盒中缓存目录
if let cachesDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first {
print("Caches Directory: \(cachesDirectory)")
}
// 获取库目录
if let libraryDirectory = fileManager.urls(for: .libraryDirectory, in: .userDomainMask).first {
print("Library Directory: \(libraryDirectory)")
}
结果示例(iOS 上沙盒路径) #
文档目录(
documentDirectory
+.userDomainMask
):/var/mobile/Containers/Data/Application/1234-5678-ABCD/Documents
缓存目录(
cachesDirectory
+.userDomainMask
):/var/mobile/Containers/Data/Application/1234-5678-ABCD/Library/Caches
库目录(
libraryDirectory
+.userDomainMask
):/var/mobile/Containers/Data/Application/1234-5678-ABCD/Library