FileManager เป็นคลาสจาก Foundation framework ที่ให้อินเทอร์เฟซสำหรับทำงานกับระบบไฟล์บน iOS, macOS และแพลตฟอร์ม Apple อื่นๆ ช่วยให้คุณสร้าง อ่าน ย้าย และลบไฟล์และไดเรกทอรี รวมถึงจัดการเมทาดาทาและสิทธิ์การเข้าถึง ใน iOS การดำเนินการ FileManager ทั้งหมดถูกจำกัดโดย Sandbox ของแอป ตาม เอกสารสำหรับนักพัฒนา Apple (2026) FileManager เป็นเธรดที่ปลอดภัยและสามารถใช้งานได้จากเธรดพื้นหลัง แต่การดำเนินการระบบไฟล์ทั้งหมดต้องดำเนินการโดยคำนึงถึงแซนด์บ็อกซ์และสิทธิ์การเข้าถึง Security-Scoped Bookmarks
ประเด็นสำคัญ
FileManager เป็นคลาสซิงเกิลตันจาก Foundation framework ที่ให้ API แบบรวมสำหรับการโต้ตอบกับระบบไฟล์บนทุกแพลตฟอร์ม Apple สามารถใช้งานได้ผ่าน FileManager.default หรือโดยการสร้างอินสแตนซ์พร้อมตัวแทนที่กำหนดเอง
ความสามารถหลักของคลาสรวมถึง: การตรวจสอบการมีอยู่ของไฟล์ (fileExists), การสร้างไดเรกทอรี (createDirectory), การคัดลอกและย้าย (copyItem, moveItem), การลบ (removeItem), การรับแอตทริบิวต์ (attributesOfItem) และเนื้อหาไดเรกทอรี (contentsOfDirectory) FileManager เกี่ยวข้องอย่างใกล้ชิดกับ NSData, String และ JSONEncoder/Decoder สำหรับการทำให้ข้อมูลเป็นลำดับ
FileManager เป็น เธรดที่ปลอดภัย: Apple รับประกันการเรียกเมธอดที่ปลอดภัยจากเธรดต่างๆ อย่างไรก็ตาม การดำเนินการระบบไฟล์อาจช้าสำหรับไฟล์ขนาดใหญ่ ดังนั้น Apple แนะนำให้ดำเนินการในคิวพื้นหลัง (DispatchQueue.global) และเรียกเมธอด FileManagerDelegate เพื่อรายงานความคืบหน้า
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 มี สามไดเรกทอรีหลัก ที่เข้าถึงได้ผ่าน FileManager ภายใน Sandbox: Documents, Library และ tmp แต่ละแห่งมีวัตถุประสงค์และกฎการสำรองข้อมูลของตัวเองซึ่งจำเป็นต้องปฏิบัติตามเพื่อผ่านการตรวจสอบ App Store
Documents — สำหรับข้อมูลผู้ใช้ที่ควรเก็บรักษาระหว่างการเปิดแอปและสำรองข้อมูลไปยัง iCloud Library — สำหรับไฟล์แอป: แคช (Caches), การตั้งค่า (Preferences), ฐานข้อมูล (Application Support) tmp — สำหรับไฟล์ชั่วคราวที่ระบบสามารถลบได้ตลอดเวลาระหว่างการเปิดแอป
| ไดเรกทอรี | URL ของ FileManager | สำรองข้อมูล | การใช้งาน |
|---|---|---|---|
| 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 สำหรับการอ่านและเขียนไฟล์ขนาดใหญ่ในลักษณะสตรีม ซึ่งไม่โหลดไฟล์ทั้งหมดเข้าสู่หน่วยความจำ
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 — ซึ่งรับประกันว่าไฟล์จะไม่เสียหายหากการเขียนล้มเหลว: ข้อมูลจะถูกบันทึกไปยังไฟล์ชั่วคราวก่อน จากนั้นถูกย้ายไปยังเส้นทางเป้าหมายแบบอะตอมมิก ในการอ่านไฟล์ขนาดใหญ่ ให้ใช้ FileHandle ด้วย .readingMode และอ่านข้อมูลเป็นชิ้นส่วน ควบคุมการใช้หน่วยความจำ
FileManager มีเมธอดสำหรับการจัดการไดเรกทอรีอย่างสมบูรณ์: createDirectory (การสร้างโฟลเดอร์กลางทั้งหมดผ่าน withIntermediateDirectories), contentsOfDirectory (รับรายการไฟล์), enumeratorAt (การสำรวจแบบเรียกซ้ำ) และ subpathsOfDirectory (เส้นทางทั้งหมดภายในไดเรกทอรี)
เมธอด enumeratorAt ส่งคืน DirectoryEnumerator ซึ่งช่วยให้สำรวจไดเรกทอรีขนาดใหญ่ได้อย่างมีประสิทธิภาพโดยไม่ต้องโหลดเนื้อหาทั้งหมดเข้าสู่หน่วยความจำ รองรับการกรองผ่าน skipDescendants และให้แอตทริบิวต์ของแต่ละรายการโดยไม่ต้องสอบถามระบบไฟล์เพิ่มเติม
// การสำรวจไดเรกทอรีแบบเรียกซ้ำ
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 Drive ผ่านเมธอด URLForUbiquityContainerIdentifier ซึ่งส่งคืน URL ของไดเรกทอรี iCloud สำหรับแอป ซึ่งจำเป็นต้องเปิดใช้ความสามารถ iCloud ในโปรเจกต์และเพิ่ม entitlement ที่เหมาะสม
ไฟล์ iCloud ซิงค์โดยอัตโนมัติ แต่ FileManager มีเมธอดสำหรับการควบคุมด้วยตนเอง: startDownloadingUbiquitousItem บังคับให้ดาวน์โหลด evictUbiquitousItem ลบสำเนาท้องถิ่น และ urlOfItem(at:) ส่งคืน URL ท้องถิ่นสำหรับไฟล์ iCloud NSMetadataQuery ใช้สำหรับค้นหาไฟล์ใน iCloud
ข้อจำกัดที่สำคัญ: iCloud Drive ไม่รองรับ สำหรับไฟล์ในไดเรกทอรี Documents — เฉพาะสำหรับไฟล์ใน ubiquityContainer อย่าพยายามซิงค์ Documents ผ่าน iCloud; สำหรับสิ่งนั้นให้ใช้ NSUbiquitousKeyValueStore สำหรับข้อมูลปริมาณน้อยหรือ Core Data กับ CloudKit สำหรับโครงสร้างที่ซับซ้อน
การดำเนินการกับ FileManager อาจมีค่าใช้จ่ายสูง โดยเฉพาะบนอุปกรณ์ที่มีหน่วยความจำแฟลชช้า คำแนะนำหลักของ Apple รวมถึงการดำเนินการไฟล์ทั้งหมดในคิวพื้นหลัง การลดจำนวนการเรียก fileExistsAtPath และการแคชผลลัพธ์
เมธอด fileExists ดำเนินการเรียกระบบ stat() ซึ่งค่อนข้างช้า หากคุณตรวจสอบการมีอยู่ของไฟล์ก่อนการอ่าน ควรลองอ่านไฟล์โดยตรงและจัดการข้อผิดพลาด — ซึ่งดำเนินการ stat เดียวกันแต่หลีกเลี่ยงการเรียกระบบซ้ำซ้อน สำหรับการตรวจสอบจำนวนมาก ให้ใช้ enumeratorAt กับ resourceValues
สำหรับการ ปรับปรุงประสิทธิภาพ ในการทำงานกับข้อมูลปริมาณมาก:
Apple Instruments มีเทมเพลต File Activity สำหรับการวิเคราะห์ประสิทธิภาพการดำเนินการไฟล์ ใช้มันเพื่อระบุจุดคอขวด — ตัวอย่างเช่น การเรียก fileExists บ่อยครั้งในลูปหรือการดำเนินการเขียนบนเธรดหลัก ปัญหาประสิทธิภาพที่พบบ่อยที่สุดเกี่ยวข้องกับการเขียนไฟล์ขนาดใหญ่แบบซิงโครนัสเมื่อแอปถูกระงับ
คำถามที่พบบ่อย
FileManager เป็นคลาสของ Foundation framework สำหรับทำงานกับระบบไฟล์ของ Apple ให้ API สำหรับสร้าง อ่าน ย้าย และลบไฟล์และไดเรกทอรี ใน iOS การทำงานของมันถูกจำกัดอยู่ภายใน Sandbox ของแอป ยกเว้น Security-Scoped Bookmarks
Documents — ข้อมูลผู้ใช้ที่มีการสำรองข้อมูล iCloud Library/Caches — แคชที่ไม่มีการสำรองข้อมูล Library/Application Support — ฐานข้อมูล tmp — ไฟล์ชั่วคราว App Group Container — สำหรับข้อมูลที่ใช้ร่วมกันระหว่างแอปในกลุ่มเดียวกัน
เรียก FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first เมธอดส่งคืน URL พร้อมเส้นทางสัมบูรณ์ไปยังไดเรกทอรี Documents ภายใน Sandbox ของแอปปัจจุบัน ใช้ fileExists(atPath:) เพื่อตรวจสอบการมีอยู่
ไม่ Sandbox ของ iOS ป้องกันการเข้าถึงระบบไฟล์ของแอปพลิเคชันอื่น ข้อยกเว้น: App Groups (ไดเรกทอรีที่ใช้ร่วมกันสำหรับแอปของนักพัฒนาเดียวกัน) และ Security-Scoped Bookmarks (การเข้าถึงไฟล์ผ่าน UIDocumentPicker และ iCloud Drive)
ใช้ตัวเลือก .atomic เมื่อเขียน — ข้อมูลจะถูกบันทึกไปยังไฟล์ชั่วคราวก่อน จากนั้นย้ายไปยังเส้นทางเป้าหมายแบบอะตอมมิก ซึ่งป้องกันการเสียหายของไฟล์หากการเขียนล้มเหลว สำหรับข้อมูลขนาดใหญ่ ให้ใช้ FileHandle ด้วยการเขียนเป็นชิ้นส่วนขนาด 1-2 MB
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม