iOS FileManager 檔案管理
對於圖片、PDF、大型 JSON 等資料,我們需要將它們存成檔案。Swift 提供了 FileManager 來操作檔案系統。
沙盒機制 (Sandbox)
iOS App 只能存取自己的「沙盒」目錄,無法讀取其他 App 的檔案(除非透過特定的 Extension 或 Picker)。
常用的目錄有:
| 目錄 (Directory) | 用途說明 | 備份行為 |
|---|---|---|
| Documents | 存放使用者產生的重要資料。 | 會被 iCloud 備份 |
| Caches | 存放可被清除的暫存檔(如圖片快取)。 | 不會被備份,系統空間不足時可能自動刪除 |
| tmp | 存放臨時檔案,App 結束後可能被清空。 | 不會被備份 |
| Library | 存放非使用者直接產生的資料庫或設定檔。 | 預設備份 |
獲取目錄路徑
我們通常使用 FileManager.default 來獲取路徑。
func getDocumentsDirectory() -> URL {
// .documentDirectory: Documents 目錄
// .cachesDirectory: Caches 目錄
// .libraryDirectory: Library 目錄
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
檔案與目錄操作
建立目錄 (Create Directory)
在存檔案前,如果要分類(例如 Documents/Images),需要先建立資料夾。
let manager = FileManager.default
let imagesPath = getDocumentsDirectory().appendingPathComponent("Images")
do {
// withIntermediateDirectories: true 表示如果父目錄不存在,會一併建立
try manager.createDirectory(at: imagesPath, withIntermediateDirectories: true)
print("目錄建立成功")
} catch {
print("目錄建立失敗: \(error)")
}
檢查檔案是否存在 (Check Existence)
let filePath = imagesPath.appendingPathComponent("avatar.png")
if manager.fileExists(atPath: filePath.path) {
print("檔案存在")
} else {
print("檔案不存在")
}
移除檔案 (Delete)
do {
try manager.removeItem(at: filePath)
print("刪除成功")
} catch {
print("刪除失敗: \(error)")
}
寫入與讀取
最常見的是字串 (String) 和二進位資料 (Data) 的讀寫。
字串操作
let fileURL = getDocumentsDirectory().appendingPathComponent("notes.txt")
// --- 寫入 ---
do {
let text = "Hello, FileManager!"
try text.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print("寫入失敗: \(error)")
}
// --- 讀取 ---
do {
let savedText = try String(contentsOf: fileURL)
print("讀取內容: \(savedText)")
} catch {
print("讀取失敗: \(error)")
}
圖片操作 (Convert to Data)
要儲存 UIImage,需要先轉換成 Data。
func saveImage(image: UIImage, name: String) {
// 1. 轉成 Data (JPEG 壓縮品質 0.8)
guard let data = image.jpegData(compressionQuality: 0.8) else { return }
// 2. 設定路徑
let filename = getDocumentsDirectory().appendingPathComponent(name)
// 3. 寫入
do {
try data.write(to: filename)
} catch {
print("圖片儲存失敗: \(error)")
}
}
複製與移動 (Copy & Move)
let originalURL = getDocumentsDirectory().appendingPathComponent("old.txt")
let newURL = getDocumentsDirectory().appendingPathComponent("new.txt")
do {
// 移動 (重新命名)
try manager.moveItem(at: originalURL, to: newURL)
// 複製
// try manager.copyItem(at: originalURL, to: newURL)
} catch {
print("操作失敗: \(error)")
}
讀取檔案屬性
你可以獲取檔案的大小、建立日期等資訊。
do {
let attributes = try manager.attributesOfItem(atPath: fileURL.path)
if let fileSize = attributes[.size] as? Int64 {
print("檔案大小: \(fileSize) bytes")
}
if let creationDate = attributes[.creationDate] as? Date {
print("建立日期: \(creationDate)")
}
} catch {
print("無法讀取屬性: \(error)")
}