FileManager — 是什么,iOS 文件系统操作

作者: IT Sectr 发布日期: 2026-07-09 阅读时间: 9 分钟

FileManager — 是 Foundation 框架中的一个类,提供用于操作 iOS、macOS 和其他 Apple 平台文件系统的接口。它可以创建、读取、移动和删除文件及目录,以及管理元数据和访问权限。在 iOS 中,所有 FileManager 操作都受限于应用的沙盒范围。根据 Apple Developer Documentation (2026),FileManager 是线程安全的,可以从后台线程使用,但所有文件系统操作都必须考虑沙盒和 Security-Scoped Bookmarks 访问权限。

要点

  • FileManager — Foundation 中用于文件系统操作的主要类:读取、写入、移动、删除文件。
  • 沙盒限制 FileManager 只能访问应用的目录 — Documents、Library、tmp 和 App Group。
  • 基于 URL 的 API(fileManager.urls)在现代应用中比基于字符串的(NSHomeDirectory)更优。
  • FileManagerDelegate 允许通过 shouldMoveItemAt 和 shouldRemoveItemAt 跟踪和控制文件操作。
  • iCloud Drive 可通过 FileManager 访问,前提是启用了 ubiquityContainer 并具有相应的 entitlements。

什么是 FileManager

FileManager — 是 Foundation 框架中的一个单例类,提供统一的 API 用于在所有 Apple 平台上与文件系统交互。可通过 FileManager.default 或通过创建带有自定义委托的实例来访问。

该类的主要功能包括:检查文件是否存在(fileExists)、创建目录(createDirectory)、复制和移动(copyItem、moveItem)、删除(removeItem)、获取属性(attributesOfItem)和目录内容(contentsOfDirectory)。FileManager 与 NSData、String 和 JSONEncoder/Decoder 紧密相关,用于数据序列化。

FileManager 是线程安全的:Apple 保证从不同线程调用方法的安全性。然而,文件系统操作在处理大文件时可能会很慢,因此 Apple 建议在后台队列(DispatchQueue.global)中执行它们,并调用 FileManagerDelegate 方法来通知进度。

swift
let fileManager = FileManager.default
let documentsURL = fileManager.urls(
    for: .documentDirectory,
    in: .userDomainMask
).first!

let fileURL = documentsURL.appendingPathComponent("data.plist")

if fileManager.fileExists(atPath: fileURL.path) {
    print("File exists at \(fileURL.path)")
}

iOS 应用的主要目录

每个 iOS 应用在沙盒中有三个主要目录可通过 FileManager 访问:Documents、Library 和 tmp。每个目录都有其用途和备份规则,遵守这些规则对于通过 App Store 审核至关重要。

Documents — 用于用户数据,需要在启动之间保留并备份到 iCloud。Library — 用于应用文件:缓存(Caches)、偏好设置(Preferences)、数据库(Application Support)。tmp — 用于临时文件,系统可在应用启动之间的任何时候删除这些文件。

目录FileManager URL备份用途
Documents.documentDirectory用户数据、文件、导出
Library/Caches.cachesDirectory图片缓存、临时数据
Library/Preferences.libraryDirectory + "/Preferences"UserDefaults、应用设置
Library/Application Support.applicationSupportDirectory数据库、CoreData、Realm
tmp.tmpDirectory (NSTemporaryDirectory)会话临时文件

Apple 规则:如果文件可以从互联网恢复或重新创建 — 应存储在 Caches 中(无备份)。如果文件包含用户数据 — 存储在 Documents 中(有备份)。文件放置不正确是应用被拒绝的常见原因之一,因为 Apple 会检查是否符合 Storage & iCloud Backup Guidelines。

文件的读取和写入

FileManager 本身不提供读取文件内容的方法 — 这需要使用 NSData(contentsOf)、String(contentsOf) 或 FileHandle 方法。FileManager 负责文件的管理:检查存在性、移动、复制、删除。

写入数据时使用 createFile(atPath:contents:attributes:) 方法或高级 API — data.write(to:)、JSONEncoder.encode 和 PropertyListEncoder。FileManager 还提供 FileHandle 用于流式读取和写入大文件,而无需将整个文件加载到内存中。

swift
struct UserSettings: Codable {
    let username: String
    let isDarkMode: Bool
    let fontSize: Int
}

let settings = UserSettings(
    username: "developer",
    isDarkMode: true,
    fontSize: 16
)

// 将 JSON 写入 Documents
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(settings)
let url = documentsURL.appendingPathComponent("settings.json")
try data.write(to: url, options: .atomic)

// 读取 JSON
let loadedData = try Data(contentsOf: url)
let loadedSettings = try JSONDecoder()
    .decode(UserSettings.self, from: loadedData)

写入时使用 options: .atomic — 这确保在写入失败时文件不会损坏:数据首先保存到临时文件,然后原子性地移动到目标路径。读取大文件时,使用带有 .readingMode 的 FileHandle,分块读取数据,控制内存使用。

目录管理

FileManager 提供了完整的目录管理方法:createDirectory(通过 withIntermediateDirectories 创建所有中间文件夹)、contentsOfDirectory(获取文件列表)、enumeratorAt(递归遍历)和 subpathsOfDirectory(目录内的所有路径)。

enumeratorAt 方法返回一个 DirectoryEnumerator,可以高效地遍历大目录而无需将整个内容加载到内存中。它支持通过 skipDescendants 进行过滤,并提供每个元素的属性,而无需额外查询文件系统。

swift
// 递归目录遍历
if let enumerator = fileManager.enumerator(
    at: documentsURL,
    includingPropertiesForKeys: [.fileSizeKey, .isDirectoryKey]
) {
    for case let fileURL as URL in enumerator {
        let attrs = try fileURL.resourceValues(
            for: [.fileSizeKey, .isDirectoryKey]
        )
        if attrs.isDirectory == false {
            let size = attrs.fileSize ?? 0
            print("File: \(fileURL.lastPathComponent), Size: \(size) bytes")
        }
    }
}

删除目录时使用 removeItem(at:)。注意:在 iOS 中删除目录是不可逆的 — 文件不会像 macOS 那样进入废纸篓。删除前请确保不再使用此目录中的文件,并在后台线程上执行操作,因为删除大量文件可能会阻塞 UI。

FileManager 与 iCloud

FileManager 通过 URLForUbiquityContainerIdentifier 方法与 iCloud Drive 集成,该方法返回应用的 iCloud 目录 URL。使用前需要在项目中启用 iCloud capability 并添加相应的 entitlement。

iCloud 文件会自动同步,但 FileManager 提供了手动控制的方法:startDownloadingUbiquitousItem 强制开始下载,evictUbiquitousItem 删除本地副本,urlOfItem(at:) 返回 iCloud 文件的本地 URL。NSMetadataQuery 用于在 iCloud 中搜索文件。

关键限制:iCloud Drive 不支持 Documents 目录中的文件 — 仅支持 ubiquityContainer 中的文件。不要尝试通过 iCloud 同步 Documents;对于少量数据,请使用 NSUbiquitousKeyValueStore,对于复杂结构,请使用 Core Data 和 CloudKit。

FileManager 性能

使用 FileManager 的操作可能代价高昂,尤其是在闪存较慢的设备上。Apple 的主要建议包括:在后台队列中执行所有文件操作、尽量减少 fileExistsAtPath 调用次数以及使用结果缓存。

fileExists 方法执行系统调用 stat(),这相对较慢。如果要在读取文件前检查其是否存在,最好直接尝试读取并处理错误 — 这执行相同的 stat,但消除了双重系统调用。对于批量检查,使用带有 resourceValues 的 enumeratorAt。

优化处理大量数据:

  • 使用 FileHandle 流式处理大文件
  • 缓存频繁使用的目录的 fileManager.urls 结果
  • 在细粒度队列中执行批量操作,避免阻塞主线程
  • 使用 CoordinatedFileManager 实现多线程安全访问

Apple Instruments 提供了 File Activity 模板用于分析文件操作。使用它可以识别瓶颈 — 例如,循环中频繁调用 fileExists 或在主线程上的写入操作。最常见的性能问题与在应用最小化时同步写入大文件有关。

常见问题

iOS 中的 FileManager 是什么?

FileManager — 是 Foundation 框架中用于操作 Apple 文件系统的类。提供用于创建、读取、移动、删除文件和目录的 API。在 iOS 中,其操作受限于应用沙盒范围,Security-Scoped Bookmarks 除外。

iOS 中通过 FileManager 可以访问哪些目录?

Documents — 用户数据,在 iCloud 中有备份。Library/Caches — 无备份的缓存。Library/Application Support — 数据库。tmp — 临时文件。App Group Container — 用于同一组应用之间的共享数据。

如何通过 FileManager 获取 Documents 的路径?

调用 FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first。该方法返回包含当前应用沙盒内 Documents 目录绝对路径的 URL。使用 fileExists(atPath:) 检查目录是否存在。

能否通过 FileManager 访问其他应用的文件?

不能,iOS 沙盒禁止访问其他应用的文件系统。例外情况:App Groups(同一开发者应用的共享目录)和 Security-Scoped Bookmarks(通过 UIDocumentPicker 和 iCloud Drive 访问文件)。

如何通过 FileManager 安全地写入文件?

写入时使用 .atomic 选项 — 数据首先保存到临时文件,然后原子性地移动到目标路径。这可以防止写入失败时文件损坏。对于大数据,使用 FileHandle 以 1-2 MB 的块进行写入。

总结

  • FileManager — iOS 中所有文件系统操作的核心 Foundation 类:从检查存在性到递归遍历目录。
  • Documents、Library、tmp — 应用的三个主要目录,具有不同的备份和生命周期规则。
  • 基于 URL 的 API 优于基于字符串的路径,以便与沙盒和 Security-Scoped Bookmarks 兼容。
  • FileHandle 和流式处理 — 在不耗尽内存的情况下处理大文件的唯一方法。
  • FileManagerDelegate 允许通过 should 方法控制移动、复制和删除操作。
  • iCloud 集成 可通过 ubiquityContainer 和 NSMetadataQuery 用于处理云文件。
  • 文件操作的性能至关重要 — 请在后台队列中执行并尽量减少 fileExists 调用。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读