Swift 管理文件的FileManager类
Swift 管理文件的FileManager类

Swift 管理文件的FileManager类

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 在系统的临时目录下保存并控制文件的路径(包括命名)。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注