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

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

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

Начать курс

Работа с файловой системой в Kotlin: от теории к практике

Работа с файловой системой — одна из базовых задач, с которой сталкивается каждый разработчик. В Kotlin, благодаря его тесной интеграции с Java и собственным удобным расширениям, управление файлами и каталогами становится интуитивно понятным и лаконичным. В этой статье мы разберём ключевые операции: создание, чтение, запись и удаление файлов, а также работу с директориями. Все примеры написаны на Kotlin и готовы к использованию в ваших проектах.

Основы: подключение и первые шаги

Kotlin не имеет собственной отдельной библиотеки для работы с файловой системой — он полностью использует мощь java.io.File, добавляя к нему множество extension-функций. Это означает, что вы можете использовать привычные Java-методы, но с более коротким и безопасным синтаксисом.

import java.io.File

fun main() {
    val file = File("example.txt")
    println(file.exists()) // false, если файла нет
}

Основной класс — java.io.File. Он представляет собой абстракцию пути к файлу или директории, не обязательно существующего на диске.

Чтение и запись файлов в Kotlin

Kotlin предлагает элегантные способы чтения и записи, которые избавляют от необходимости вручную управлять потоками и закрывать ресурсы.

Чтение всего содержимого файла

Самый простой способ — использовать функцию readText(). Она читает весь файл в одну строку.

fun readEntireFile() {
    val file = File("data.txt")
    if (file.exists()) {
        val content: String = file.readText()
        println(content)
    } else {
        println("Файл не найден")
    }
}

Если файл большой, лучше читать построчно:

fun readLines() {
    File("log.txt").useLines { lines ->
        lines.forEach { line ->
            println(line)
        }
    }
    // useLines автоматически закроет поток
}

Запись в файл

Для записи используйте writeText() (перезаписывает файл) или appendText() (добавляет в конец).

fun writeToFile() {
    val file = File("output.txt")
    file.writeText("Привет, Kotlin!\n")
    file.appendText("Это вторая строка.")
    
    println(file.readText())
    // Вывод:
    // Привет, Kotlin!
    // Это вторая строка.
}

Для более сложных данных (например, запись списка строк) удобно использовать writeLines():

fun writeListOfLines() {
    val lines = listOf("Строка 1", "Строка 2", "Строка 3")
    File("list.txt").writeLines(lines)
}

Создание, копирование и удаление файлов и директорий

Управление файловой структурой — ещё одна частая задача. Рассмотрим основные операции.

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

Метод createNewFile() создаёт новый пустой файл, если он ещё не существует. Для создания директорий используйте mkdir() (создаёт только последнюю папку в пути) или mkdirs() (создаёт все недостающие родительские каталоги).

fun createStructure() {
    val dir = File("my_project/src/main")
    if (dir.mkdirs()) {
        println("Директория создана: ${dir.absolutePath}")
    }
    
    val newFile = File(dir, "config.ini")
    if (newFile.createNewFile()) {
        println("Файл создан: ${newFile.name}")
    }
}

Копирование и перемещение

В Kotlin нет встроенной функции copyTo? На самом деле есть! Метод copyTo() позволяет легко копировать файлы, а renameTo() — переименовывать или перемещать.

fun copyAndMove() {
    val source = File("source.txt")
    val destination = File("backup/source_copy.txt")
    
    // Копирование
    source.copyTo(destination, overwrite = true)
    
    // Переименование (перемещение)
    val renamed = File("new_name.txt")
    source.renameTo(renamed)
}

Удаление

Для удаления одного файла достаточно вызвать delete(). Для рекурсивного удаления всей директории с содержимым используйте deleteRecursively().

fun deleteExamples() {
    val file = File("temp.txt")
    if (file.delete()) {
        println("Файл удалён")
    }
    
    val dir = File("old_project")
    if (dir.deleteRecursively()) {
        println("Директория и всё её содержимое удалены")
    }
}

Обход файловой системы и работа с путями

Часто требуется пройтись по всем файлам в папке или найти файлы по расширению. Kotlin предоставляет удобные методы для этого.

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

Метод listFiles() возвращает массив файлов в директории. Его можно отфильтровать с помощью filter.

fun listFilesInDirectory() {
    val dir = File(".")
    val files = dir.listFiles()
    
    files?.forEach { file ->
        println("${file.name} (${if (file.isDirectory) "папка" else "файл"})")
    }
    
    // Только файлы .txt
    val txtFiles = dir.listFiles { file -> file.extension == "txt" }
    txtFiles?.forEach { println("Найден txt: ${it.name}") }
}

Рекурсивный обход с walk()

Функция walk() возвращает последовательность всех файлов и папок внутри директории. Вы можете указать направление обхода (сверху вниз или снизу вверх).

fun walkThrough() {
    val startDir = File("src")
    
    // Обход всех файлов (включая вложенные папки)
    startDir.walk().forEach { file ->
        println(file.absolutePath)
    }
    
    // Обход только файлов (исключая папки)
    startDir.walk()
        .filter { it.isFile }
        .forEach { println("Файл: ${it.name}") }
    
    // Поиск всех файлов .kt
    val kotlinFiles = startDir.walk()
        .filter { it.extension == "kt" }
        .toList()
    println("Найдено Kotlin-файлов: ${kotlinFiles.size}")
}

Параметр FileWalkDirection.TOP_DOWN (по умолчанию) обходит папки сверху вниз, а BOTTOM_UP

Блоги

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