JavaRush /Курси /JAVA 25 SELF /Робота з директоріями: створення, видалення, перегляд вмі...

Робота з директоріями: створення, видалення, перегляд вмісту

JAVA 25 SELF
Рівень 35 , Лекція 4
Відкрита

1. Створення директорій

Директорія (вона ж папка) — це не просто контейнер для файлів, а основа організації даних на диску. У застосунках ми постійно створюємо директорії для вхідних/вихідних даних, логів, тимчасових файлів тощо. Сучасний API java.nio.file робить це зручно та платформонезалежно.

Розгляньмо, як створювати, видаляти та переглядати вміст директорій за допомогою класів Files, Path і Paths.

Files.createDirectory(path)

Створює одну директорію за вказаним шляхом. Якщо батьківської директорії немає — буде викинуто виняток.

import java.nio.file.*;

public class DirectoryDemo {
    public static void main(String[] args) throws Exception {
        Path dir = Paths.get("testDir");
        if (!Files.exists(dir)) {
            Files.createDirectory(dir);
            System.out.println("Директорію створено: " + dir.toAbsolutePath());
        } else {
            System.out.println("Директорія вже існує: " + dir.toAbsolutePath());
        }
    }
}

Якщо ви спробуєте створити директорію, яка вже існує, отримаєте FileAlreadyExistsException.

Files.createDirectories(path)

Створює увесь ланцюжок директорій. Якщо якась із проміжних директорій відсутня — її буде створено автоматично. Якщо частина ланцюжка вже існує — помилки не буде.

Path nestedDir = Paths.get("parent/child/grandchild");
Files.createDirectories(nestedDir);
System.out.println("Створено ланцюжок директорій: " + nestedDir.toAbsolutePath());

Це наче ви попросили Java збудувати не лише будинок, а й підʼїзд і вулицю, якщо їх ще не було.

Типовий приклад: створюємо структуру для проєкту

Припустімо, потрібно зберігати звіти в папку output/reports/2024. Не перевіряйте кожну директорію вручну — використовуйте createDirectories.

Path reportsPath = Paths.get("output/reports/2024");
Files.createDirectories(reportsPath);

Java сама розбереться, що вже є, а що потрібно створити.

2. Видалення файлів і директорій

Files.delete(path)

Видаляє файл або порожню директорію. Якщо директорія не порожня — буде викинуто DirectoryNotEmptyException.

Path dir = Paths.get("testDir");
try {
    Files.delete(dir);
    System.out.println("Директорію видалено: " + dir.toAbsolutePath());
} catch (DirectoryNotEmptyException e) {
    System.out.println("Неможливо видалити: директорія не порожня!");
}

Files.deleteIfExists(path)

Працює як delete, але не викидає виняток, якщо обʼєкта немає. Повертає true, якщо обʼєкт було видалено, і false — якщо обʼєкта не було.

Path file = Paths.get("output/reports/2024/report.txt");
if (Files.deleteIfExists(file)) {
    System.out.println("Файл видалено.");
} else {
    System.out.println("Файл не знайдено, нічого не видалено.");
}

Як видалити непорожню директорію?

Непорожню директорію просто так видалити не можна. Спочатку потрібно видалити весь її вміст (файли та піддиректорії), а потім саму папку. Робиться це рекурсивно, наприклад, через Files.walkFileTree:

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class DeleteDirectoryRecursively {
    public static void main(String[] args) throws IOException {
        Path dir = Paths.get("parent");
        if (Files.exists(dir)) {
            Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file);
                    return FileVisitResult.CONTINUE;
                }
                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                }
            });
            System.out.println("Директорію та весь її вміст видалено.");
        }
    }
}

Якщо ви лише починаєте, не лякайтеся цього коду — згодом розберемо walkFileTree докладніше.

3. Перегляд вмісту директорії

Files.list(path)

Повертає Stream<Path> — потік шляхів. Ви можете обробляти вміст директорії через Stream API. Кожен запис — файл або піддиректорія (без рекурсії!).

Path dir = Paths.get("output/reports");
if (Files.exists(dir) && Files.isDirectory(dir)) {
    try (var stream = Files.list(dir)) {
        stream.forEach(path -> System.out.println(path.getFileName()));
    }
}

Важлива деталь: потік обовʼязково слід закривати, тому використовуємо try‑with‑resources.

Приклад: виводимо імена файлів і піддиректорій

Path reports2024 = Paths.get("output/reports/2024");
try (var stream = Files.list(reports2024)) {
    stream.forEach(path -> {
        String type = Files.isDirectory(path) ? "директорія" : "файл";
        System.out.println(path.getFileName() + " — " + type);
    });
}

Отримання списку файлів у вигляді колекції

List<Path> files = Files.list(reports2024)
    .filter(Files::isRegularFile)
    .toList();

System.out.println("Файли в папці:");
files.forEach(System.out::println);

Важливо: Files.list(path) повертає лише вміст поточної директорії (верхній рівень). Для рекурсивного обходу використовуйте Files.walk(path).

4. Практика: міні‑файловий менеджер

Утиліта створює директорію mydata/logs, файл log1.txt, виводить вміст директорії та потім усе видаляє.

import java.nio.file.*;
import java.io.IOException;

public class MiniFileManager {
    public static void main(String[] args) throws IOException {
        Path logsDir = Paths.get("mydata/logs");
        Files.createDirectories(logsDir);

        Path logFile = logsDir.resolve("log1.txt");
        Files.writeString(logFile, "Привіт, лог!");

        System.out.println("Вміст папки " + logsDir + ":");
        try (var stream = Files.list(logsDir)) {
            stream.forEach(path -> System.out.println(" - " + path.getFileName()));
        }

        Files.deleteIfExists(logFile);
        Files.deleteIfExists(logsDir);
        System.out.println("Файл і папка видалені.");
    }
}

Коментарі до коду:

  • Files.createDirectories гарантує створення всього ланцюжка.
  • resolve — зручний спосіб додати до шляху імʼя файлу.
  • Закриваємо потік від Files.list через try‑with‑resources — особливо критично у Windows.

5. Особливості та нюанси

Перевірка існування

Перед створенням/видаленням корисно перевірити, чи існує шлях:

if (!Files.exists(path)) {
    Files.createDirectory(path);
}

Права доступу

Якщо у програми немає прав на створення/видалення — отримаєте AccessDeniedException. Наприклад, створення директорії у корені диска від звичайного користувача майже завжди закінчиться помилкою.

Порожня та непорожня директорія

Видалити можна лише порожню директорію (Files.delete). Для видалення разом із вмістом використовуйте рекурсивний обхід (walkFileTree).

Платформонезалежність

API java.nio.file коректно працює на всіх популярних ОС і враховує роздільники шляхів. Для побудови шляхів використовуйте Paths.get і Path.resolve, а не склеюйте рядки.

Символічні посилання

У базових задачах про них можна не думати, але якщо зустрінете «незвичні» записи, які не є ні звичайним файлом, ні директорією — можливо, це символічні посилання. Повернемося до них у просунутих лекціях.

6. Типові помилки під час роботи з директоріями

Помилка № 1: спроба видалити непорожню директорію простим викликом Files.delete(path). Java викине DirectoryNotEmptyException. Спочатку видаліть вміст, потім саму папку.

Помилка № 2: забули закрити потік із Files.list(). Якщо не використовувати try‑with‑resources, потік залишиться відкритим, і у Windows можлива помилка під час видалення директорії.

Помилка № 3: створення директорії без перевірки наявності батьківської. Виклик Files.createDirectory для шляху виду parent/child, коли parent не існує, призведе до NoSuchFileException. Використовуйте Files.createDirectories.

Помилка № 4: використання абсолютних шляхів без потреби. Віддавайте перевагу відносним шляхам у межах проєкту — так код буде переноснішим.

Помилка № 5: не обробляється IOException. Будь‑яка операція з файловою системою може завершитися помилкою. Загортайте в try-catch або передавайте виняток вище.

Помилка № 6: спроба створити/видалити у папці, до якої немає прав. У цьому разі отримаєте AccessDeniedException. Перевірте контекст запуску та права доступу.

1
Опитування
Робота з файлами, рівень 35, лекція 4
Недоступний
Робота з файлами
Робота з файлами
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ