JavaRush /Курси /JAVA 25 SELF /Робота з тимчасовими файлами та директоріями

Робота з тимчасовими файлами та директоріями

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

1. Створення тимчасових файлів: Files.createTempFile

Тимчасові файли потрібні для зберігання проміжних даних, кешу або будь-яких результатів, які не розраховані на довготривале зберігання. Як правило, вони «живуть» рівно стільки, скільки працює програма, або поки не зникає потреба в цих даних.

Найчастіше тимчасові файли використовують під час завантаження великих документів (спочатку завантажуємо їх у тимчасову папку, а потім переносимо в потрібне місце), під час кешування інформації, яку можна перерахувати або отримати знову, для зберігання проміжних результатів під час оброблення великих масивів даних, а також для обміну даними між частинами програми чи потоками. Ще один частий сценарій — тести: зручніше писати в тимчасові файли, ніж захаращувати робочі директорії.

Можна сказати, що тимчасові файли — це чорновики для програми. Вони не для публіки, але без них роботу не завжди виконаєш.

У Java створити такий файл дуже просто — буквально одним рядком. Для цього є метод Files.createTempFile.

Простий приклад

import java.nio.file.*;

public class TempFileExample {
    public static void main(String[] args) throws Exception {
        // Створюємо тимчасовий файл із префіксом "myapp_" і суфіксом ".tmp"
        Path tempFile = Files.createTempFile("myapp_", ".tmp");
        System.out.println("Тимчасовий файл створено: " + tempFile);

        // Можна записати туди дані
        Files.writeString(tempFile, "Це тимчасові дані");

        // Читаємо назад
        String data = Files.readString(tempFile);
        System.out.println("Вміст: " + data);
    }
}

Що відбувається?

  • Файл створюється в системній тимчасовій директорії (зазвичай це "/tmp" у Linux або "C:\\Users\\<ім’я>\\AppData\\Local\\Temp" у Windows).
  • Ім’я файлу буде приблизно таким: "myapp_1234567890.tmp".
  • Файл уже існує на диску, з ним можна працювати як зі звичайним.

Аргументи методу

  • Перший аргумент — префікс імені файлу (наприклад, "myapp_").
  • Другий аргумент — суфікс (наприклад, ".tmp"). Якщо його не вказати, буде просто ".tmp".
  • Якщо обидва аргументи — null, ім’я буде за замовчуванням.

Куди зберігається файл?

Типово файл зберігається в системну тимчасову директорію. Але ви можете вказати власну:

Path tempDir = Paths.get("my_temp_folder");
Files.createDirectories(tempDir); // Створюємо, якщо немає
Path tempFile = Files.createTempFile(tempDir, "prefix_", ".txt");

2. Створення тимчасових директорій: Files.createTempDirectory

Іноді потрібен не просто тимчасовий файл, а ціла тимчасова папка — наприклад, для розпакування архіву або тимчасового зберігання багатьох файлів.

Приклад

import java.nio.file.*;

public class TempDirExample {
    public static void main(String[] args) throws Exception {
        // Створюємо тимчасову директорію з префіксом "work_"
        Path tempDir = Files.createTempDirectory("work_");
        System.out.println("Тимчасова папка: " + tempDir);

        // У ній можна створювати файли
        Path fileInTempDir = Files.createTempFile(tempDir, "file_", ".dat");
        System.out.println("Тимчасовий файл усередині: " + fileInTempDir);
    }
}

Особливості:

  • Ім’я папки буде приблизно таким: "work_1234567890".
  • Типово — у системній тимчасовій директорії, але можна вказати будь-яку іншу.

Вказання директорії

Path baseDir = Paths.get("my_temp_work");
Files.createDirectories(baseDir);
Path tempDir = Files.createTempDirectory(baseDir, "session_");

3. Видалення тимчасових файлів і директорій

Ось тут криється один із головних «підводних каменів» Java: тимчасові файли й папки не видаляються автоматично! Якщо ви їх не приберете, вони залишаться на диску й тішитимуть вас своєю присутністю довгі роки (або до наступного прибирання системою).

Як видаляти тимчасові файли?

  • Вручну: після завершення роботи з файлом викличте Files.delete(...) або Files.deleteIfExists(...).
  • Наприкінці програми: можна використати старий добрий метод File.deleteOnExit(), але тільки для об’єктів типу File, а не Path.

Приклад: видалення тимчасового файлу

import java.nio.file.*;

public class TempFileDeleteExample {
    public static void main(String[] args) throws Exception {
        Path tempFile = Files.createTempFile("demo_", ".tmp");
        System.out.println("Створено: " + tempFile);

        // ... працюємо з файлом

        // Видаляємо файл
        Files.deleteIfExists(tempFile);
        System.out.println("Видалено: " + tempFile);
    }
}

Використання deleteOnExit()

import java.io.File;

public class DeleteOnExitDemo {
    public static void main(String[] args) throws Exception {
        File tempFile = File.createTempFile("legacy_", ".tmp");
        System.out.println("Створено: " + tempFile);

        // Позначаємо файл на видалення під час завершення JVM
        tempFile.deleteOnExit();
    }
}

Увага!
Метод deleteOnExit() працює тільки з File, а не з Path. Якщо ви використовуєте сучасний API (Path і Files), видаляйте вручну.

Видалення тимчасових директорій

Видалити тимчасову папку можна лише, якщо вона порожня:

Files.delete(tempDir); // згенерує виняток, якщо всередині щось залишилося

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

4. Практичні рекомендації

Де зберігати тимчасові файли?

Системна тимчасова директорія:
Використовуйте її за замовчуванням, якщо немає особливих вимог. Отримати шлях можна так:

String tempDir = System.getProperty("java.io.tmpdir");
System.out.println("Системна temp-папка: " + tempDir);

Власна папка:
Якщо безпека або організація важливі — створіть окрему папку (наприклад, у каталозі застосунку).

Безпека

  • Не зберігайте тимчасові файли у загальнодоступних папках — особливо якщо там може бути щось конфіденційне.
  • Очищайте тимчасові файли після використання — інакше вони накопичуватимуться та займатимуть місце.

Очищення у разі помилок

Якщо під час виконання програми сталася помилка, не забудьте видалити тимчасові файли. Для цього зручно використовувати блоки try-finally:

Path tempFile = Files.createTempFile("task_", ".tmp");
try {
    // використовуємо файл
} finally {
    Files.deleteIfExists(tempFile);
}

Тимчасові файли й тестування

У тестах часто використовують тимчасові файли та папки для ізоляції даних. Після тесту — обов’язково видаляйте все створене!

5. Приклад: тимчасова робоча директорія для обробки даних

Припустімо, ви пишете програму, яка обробляє архів і тимчасово розпаковує файли. Для цього зручно створити тимчасову папку, а після завершення роботи — видалити її.

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

public class TempWorkDirExample {
    public static void main(String[] args) throws IOException {
        // Створюємо тимчасову директорію
        Path tempWorkDir = Files.createTempDirectory("unzip_");
        System.out.println("Тимчасова робоча папка: " + tempWorkDir);

        try {
            // Тут могло б бути розпакування архіву
            Path tempFile = Files.createTempFile(tempWorkDir, "file_", ".txt");
            Files.writeString(tempFile, "Тимчасові дані для обробки");

            // ... працюємо з файлами

        } finally {
            // Видаляємо всі файли в папці й саму папку
            Files.walk(tempWorkDir)
                .sorted((a, b) -> b.compareTo(a)) // спочатку файли, потім папки
                .forEach(path -> {
                    try {
                        Files.deleteIfExists(path);
                    } catch (IOException ex) {
                        System.err.println("Не вдалося видалити " + path + ": " + ex.getMessage());
                    }
                });
            System.out.println("Тимчасову папку та файли видалено.");
        }
    }
}

Зверніть увагу:
Спочатку видаляємо всі файли, потім саму папку. Сортування потрібне, щоб не спробувати видалити папку до того, як видалено її вміст.

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

Помилка № 1: забули видалити тимчасовий файл або папку. Найпоширеніша проблема — тимчасові файли залишаються на диску, накопичуються й з часом призводять до «захаращення» системи. Особливо це критично для серверних застосунків і довготривалих процесів.

Помилка № 2: використовуєте deleteOnExit() для Path. Метод deleteOnExit() працює тільки з класом File, а не з Path. Якщо ви використовуєте сучасний API, доведеться видаляти вручну.

Помилка № 3: намагаєтеся видалити непорожню папку через Files.delete. Метод Files.delete() видаляє лише порожні директорії. Якщо всередині щось залишилося — буде згенеровано виняток. Для видалення непорожніх директорій використовуйте рекурсивний обхід і видалення всіх файлів.

Помилка № 4: створюєте тимчасові файли в робочій директорії проєкту. Це може призвести до випадкового видалення важливих файлів або до плутанини. Краще використовувати системну temp‑папку або окрему папку для тимчасових файлів застосунку.

Помилка № 5: не обробляєте винятки під час видалення тимчасових файлів. Якщо файл уже видалено або заблоковано, спроба видалення може згенерувати виняток. Використовуйте Files.deleteIfExists() і обробку помилок.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ