Введение
Работа с файловой системой — одна из ключевых задач при разработке приложений под iOS и macOS. Независимо от того, пишете ли вы приложение для сохранения пользовательских данных, кэширования изображений или экспорта документов, понимание основ работы с файлами в Swift является обязательным навыком. В этой статье мы разберем практические примеры работы с файловой системой: создание, чтение, запись, удаление файлов и управление директориями.
Apple предоставляет мощный API FileManager, который позволяет взаимодействовать с файловой системой как на iOS, так и на macOS. Мы рассмотрим его на реальных примерах с готовым кодом.
1. Получение путей к системным директориям
Прежде чем начать работу с файлами, нужно получить доступ к правильным директориям. В iOS и macOS каждое приложение работает в изолированной песочнице (sandbox). Для хранения данных используйте следующие пути:
Директория Documents
Используется для хранения пользовательских данных, которые должны сохраняться при обновлениях приложения и резервном копировании.
import Foundation
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
// Пример использования
let documentsURL = getDocumentsDirectory()
print("Documents path: \(documentsURL.path)")
Директория Caches
Для временных файлов, которые можно пересоздать (например, кэш изображений).
func getCachesDirectory() -> URL {
let paths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
return paths[0]
}
Директория Library/Application Support
Для хранения данных, которые не должны быть доступны пользователю напрямую, но должны сохраняться.
func getApplicationSupportDirectory() -> URL {
let paths = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
let directory = paths[0]
// Убедимся, что директория существует
try? FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
return directory
}
2. Создание и запись файлов
Теперь, когда мы знаем, где хранить файлы, научимся их создавать и записывать данные.
Запись текстовых данных
Самый простой способ — использовать метод write(to:) у строки или Data.
func writeTextFile() {
let fileName = "example.txt"
let documentsURL = getDocumentsDirectory()
let fileURL = documentsURL.appendingPathComponent(fileName)
let content = "Hello, Swift! Это тестовый файл."
do {
try content.write(to: fileURL, atomically: true, encoding: .utf8)
print("Файл успешно создан: \(fileURL.path)")
} catch {
print("Ошибка записи файла: \(error.localizedDescription)")
}
}
Запись бинарных данных (изображения, JSON)
Для работы с бинарными данными используем Data.
func writeJSONFile() {
let fileName = "data.json"
let documentsURL = getDocumentsDirectory()
let fileURL = documentsURL.appendingPathComponent(fileName)
let dictionary: [String: Any] = [
"name": "Swift Developer",
"age": 30,
"skills": ["iOS", "macOS", "SwiftUI"]
]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted)
try jsonData.write(to: fileURL, options: .atomic)
print("JSON файл сохранен")
} catch {
print("Ошибка: \(error)")
}
}
Создание директорий
Иногда нужно создать вложенные папки для организации файлов.
func createSubdirectories() {
let documentsURL = getDocumentsDirectory()
let subDirURL = documentsURL.appendingPathComponent("Images/Thumbnails")
do {
try FileManager.default.createDirectory(
at: subDirURL,
withIntermediateDirectories: true,
attributes: nil
)
print("Директория создана: \(subDirURL.path)")
} catch {
print("Не удалось создать директорию: \(error)")
}
}
3. Чтение и проверка существования файлов
Умение читать данные так же важно, как и записывать их.
Проверка существования файла
Всегда проверяйте, существует ли файл, прежде чем пытаться его прочитать.
func fileExists(at url: URL) -> Bool {
return FileManager.default.fileExists(atPath: url.path)
}
// Проверка
let testFileURL = getDocumentsDirectory().appendingPathComponent("example.txt")
if fileExists(at: testFileURL) {
print("Файл существует")
} else {
print("Файл не найден")
}
Чтение текстового файла
func readTextFile(at url: URL) -> String? {
do {
let content = try String(contentsOf: url, encoding: .utf8)
return content
} catch {
print("Ошибка чтения файла: \(error)")
return nil
}
}
// Использование
if let content = readTextFile(at: testFileURL) {
print("Содержимое файла:\n\(content)")
}
Чтение JSON файла
func readJSONFile(at url: URL) -> [String: Any]? {
do {
let data = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: data, options: [])
return json as? [String: Any]
} catch {
print("Ошибка чтения JSON: \(error)")
return nil
}
}
Получение списка файлов в директории
Часто нужно перечислить все файлы в папке.
func listFilesInDirectory(at url: URL) -> [URL] {
do {
let fileURLs = try FileManager.default.contentsOfDirectory(
at: url,
includingPropertiesForKeys: nil,
options: .skipsHiddenFiles
)
return fileURLs
} catch {
print("Ошибка получения списка файлов: \(error)")
return []
}
}
// Пример
let files = listFilesInDirectory(at: getDocumentsDirectory())
for fileURL in files {
print("Найден файл: \(fileURL.lastPathComponent)")
}
4. Удаление и перемещение файлов
Управление файлами включает также их удаление и перемещение.
Удаление файла
func deleteFile(at url: URL) {
do {
try FileManager.default.removeItem(at: url)
print("Файл удален: \(url.lastPathComponent)")
} catch {
print("Ошибка удаления файла: \(error)")
}
}
// Использование
deleteFile(at: testFile