Работа с файловой системой в Swift: полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в работу с файловой системой в Swift

Разработка под iOS и macOS часто требует взаимодействия с файловой системой устройства. Будь то сохранение пользовательских данных, кэширование изображений или экспорт документов — умение работать с файлами и папками является обязательным навыком для любого Swift-разработчика. В этой статье мы подробно разберем, как использовать FileManager, URL и Data для выполнения всех основных операций с файловой системой.

Мы рассмотрим создание, чтение, запись и удаление файлов, а также навигацию по директориям. Все примеры кода написаны на Swift 5 и подходят как для iOS, так и для macOS проектов.

Основные компоненты: FileManager и URL

В Swift центральным классом для работы с файловой системой является FileManager. Он предоставляет методы для управления файлами, директориями и их атрибутами. Для указания путей используется структура URL, которая является более безопасной и современной альтернативой строкам.

Получение стандартных директорий

Первое, что нужно знать — как получить пути к стандартным системным директориям. Для iOS это обычно Documents, Library/Caches и tmp.

import Foundation

let fileManager = FileManager.default

// Директория Documents
guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
    fatalError("Не удалось получить Documents директорию")
}
print("Documents: \(documentsURL.path)")

// Директория Caches
guard let cachesURL = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first else {
    fatalError("Не удалось получить Caches директорию")
}
print("Caches: \(cachesURL.path)")

// Временная директория
let tempURL = fileManager.temporaryDirectory
print("Temp: \(tempURL.path)")

Создание и запись файлов

Создание файла в Swift — это комбинация создания пути и записи данных. Рассмотрим два основных подхода.

Запись текстовых данных

func createTextFile() {
    guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    
    let fileURL = documentsURL.appendingPathComponent("example.txt")
    let content = "Привет, мир! Это тестовый файл."
    
    do {
        try content.write(to: fileURL, atomically: true, encoding: .utf8)
        print("Файл успешно создан по пути: \(fileURL.path)")
    } catch {
        print("Ошибка записи файла: \(error.localizedDescription)")
    }
}

Запись бинарных данных (изображения, архивы)

func createBinaryFile() {
    guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    
    let fileURL = documentsURL.appendingPathComponent("data.bin")
    let data = Data([0x48, 0x65, 0x6C, 0x6C, 0x6F]) // "Hello" в hex
    
    do {
        try data.write(to: fileURL, options: .atomic)
        print("Бинарный файл создан")
    } catch {
        print("Ошибка: \(error)")
    }
}

Создание директорий

func createDirectory() {
    guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    
    let newDirURL = documentsURL.appendingPathComponent("MyFolder")
    
    do {
        try fileManager.createDirectory(at: newDirURL, withIntermediateDirectories: true, attributes: nil)
        print("Директория создана: \(newDirURL.path)")
    } catch {
        print("Ошибка создания директории: \(error)")
    }
}

Чтение и проверка файлов

После того как файлы созданы, их нужно уметь читать и проверять их существование.

Проверка существования файла

func fileExists(at url: URL) -> Bool {
    return fileManager.fileExists(atPath: url.path)
}

// Использование
let testURL = documentsURL.appendingPathComponent("example.txt")
if fileExists(at: testURL) {
    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: testURL) {
    print("Содержимое файла: \(content)")
}

Чтение бинарных данных

func readBinaryFile(at url: URL) -> Data? {
    do {
        let data = try Data(contentsOf: url)
        return data
    } catch {
        print("Ошибка чтения бинарного файла: \(error)")
        return nil
    }
}

Получение списка файлов в директории

func listFilesInDirectory(at url: URL) {
    do {
        let contents = try fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
        print("Содержимое директории \(url.lastPathComponent):")
        for fileURL in contents {
            print("- \(fileURL.lastPathComponent)")
        }
    } catch {
        print("Ошибка получения списка файлов: \(error)")
    }
}

Перемещение, копирование и удаление файлов

Управление файлами — это не только создание и чтение. Часто требуется перемещать или удалять данные.

Копирование файла

func copyFile(from sourceURL: URL, to destinationURL: URL) {
    do {
        try fileManager.copyItem(at: sourceURL, to: destinationURL)
        print("Файл скопирован в \(destinationURL.path)")
    } catch {
        print("Ошибка копирования: \(error)")
    }
}

Перемещение файла

func moveFile(from sourceURL: URL, to destinationURL: URL) {
    do {
        try fileManager.moveItem(at: sourceURL, to: destinationURL)
        print("Файл перемещен в \(destinationURL.path)")
    } catch {
        print("Ошибка перемещения: \(error)")
    }
}

Удаление файла или директории

func deleteItem(at url: URL) {
    do {
        try fileManager.removeItem(at: url)
        print("Элемент удален: \(url.path)")
    } catch {
        print("Ошибка удаления: \(error)")
    }
}

// Удаление файла
let fileToDelete = documentsURL.appendingPathComponent("example.txt")
deleteItem(at: fileToDelete)

// Удаление директории (вместе со всем содержимым)
let dirToDelete = documentsURL.appendingPathComponent("MyFolder")
deleteItem(at: dir                

Блоги

Рекомендаций по книгам