JavaRush /Курси /JAVA 25 SELF /Копіювання та переміщення файлів і папок

Копіювання та переміщення файлів і папок

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

1. Копіювання файлів

Метод Files.copy: базовий синтаксис

У Java для копіювання файлів і папок використовується статичний метод Files.copy з пакета java.nio.file. Ми вже з ним стикалися, але тепер вивчимо його детальніше. Базовий синтаксис Files.copy:

Files.copy(Path source, Path target, CopyOption... options)
  • source — шлях до вихідного файлу або папки.
  • target — шлях, куди копіювати.
  • options — додаткові опції (наприклад, дозволити перезапис).

Найпростіший приклад

Давайте скопіюємо файл "input.txt" із поточної директорії в папку "backup" з іменем "input_backup.txt":

import java.nio.file.*;

public class CopyExample {
    public static void main(String[] args) throws Exception {
        Path source = Path.of("input.txt");
        Path target = Path.of("backup/input_backup.txt");

        Files.copy(source, target);
        System.out.println("Файл скопійовано!");
    }
}

Важливі моменти:

  • Якщо файл призначення вже існує, буде згенеровано виняток FileAlreadyExistsException.
  • Якщо папка "backup" не існує, метод згенерує помилку — папку потрібно створити заздалегідь!

Копіювання з перезаписом

Щоб дозволити перезапис файлу, використовуйте опцію StandardCopyOption.REPLACE_EXISTING:

Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

Таблиця: основні опції копіювання

Опція Опис
StandardCopyOption.REPLACE_EXISTING
Перезаписувати файл, якщо він уже існує
StandardCopyOption.COPY_ATTRIBUTES
Копіювати атрибути (дата створення тощо)
StandardCopyOption.ATOMIC_MOVE
Атомарне переміщення (використовується лише з move)

Копіювання файлу в іншу папку

Перед копіюванням файлу переконайтеся, що цільова папка існує:

Path targetDir = Path.of("backup");
if (!Files.exists(targetDir)) {
    Files.createDirectory(targetDir);
}
Files.copy(source, targetDir.resolve("input_backup.txt"), StandardCopyOption.REPLACE_EXISTING);

Копіювання директорій: підводний камінь

Метод Files.copy уміє копіювати папки лише як «порожню оболонку» — вміст (файли та підпапки) не копіюється! Якщо ви спробуєте скопіювати папку з файлами, отримаєте тільки порожню директорію. Для копіювання цілих директорій із вмістом потрібен рекурсивний обхід і ручне копіювання кожного файлу (до цього ще повернемося в наступних лекціях).

Приклад: копіюємо файл з однієї папки в іншу

Path source = Path.of("data/report.txt");
Path target = Path.of("backup/report.txt");

Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

Обробка помилок під час копіювання

Копіювання може завершитися невдачею з різних причин: немає доступу, файл зайнятий, бракує місця, файл уже є тощо. Краще завжди використовувати try-catch:

try {
    Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
    System.out.println("Копіювання успішне!");
} catch (FileAlreadyExistsException e) {
    System.out.println("Файл вже існує: " + target);
} catch (IOException e) {
    System.out.println("Помилка введення-виведення: " + e.getMessage());
}

2. Переміщення файлів і папок

Метод Files.move: синтаксис

Переміщення файлів і папок виконується за допомогою методу:

Files.move(Path source, Path target, CopyOption... options)

Де source — шлях до файлу (звідки переміщуємо), target — куди хочемо розмістити файл або папку, options — додаткові налаштування (наприклад, заміна наявного файлу).

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

Приклад: переміщення файлу в іншу папку

Path source = Path.of("data/report.txt");
Path target = Path.of("archive/report.txt");

Files.move(source, target);
System.out.println("Файл переміщено!");

Переміщення із заміною наявного файлу

Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

Переміщення папки

Path oldDir = Path.of("data/old_reports");
Path newDir = Path.of("archive/old_reports");

Files.move(oldDir, newDir);

Уся папка, включно з вкладеними файлами та підпапками, переїде в нове місце.
Але якщо в цільовій папці вже є папка з такою назвою — отримаєте помилку.

Переміщення між різними файловими системами

Якщо ви переміщаєте файл між різними дисками (наприклад, з "C:" на "D:"), під капотом відбудеться копіювання з подальшим видаленням вихідного файлу. Якщо операція не підтримується як атомарна, може бути згенеровано виняток AtomicMoveNotSupportedException.

Відмінність move від copy

  • copy — вихідний файл/папка залишається на місці, з’являється копія.
  • move — вихідний файл/папка зникає, залишається лише новий екземпляр.

3. Перейменування файлів і папок

У Java немає окремого методу «перейменувати файл». Перейменування — це окремий випадок переміщення: ви вказуєте новий шлях з іншою назвою в тій самій директорії.

Приклад: перейменування файлу

Нехай у нас є файл "report.txt", і ми хочемо перейменувати його на "report_old.txt" у тій самій папці:

Path dir = Path.of("data");
Path oldName = dir.resolve("report.txt");
Path newName = dir.resolve("report_old.txt");

Files.move(oldName, newName);
System.out.println("Файл перейменовано!");

Важливі нюанси

Якщо в цільовій директорії вже існує файл або папка з тією назвою, яку ви вказуєте, метод згенерує виняток. Щоб обійти це обмеження й дозволити заміну, можна використати опцію StandardCopyOption.REPLACE_EXISTING.

Приклад:

Path source = Paths.get("old_name.txt");
Path target = Paths.get("new_name.txt");

// Перейменуємо файл, якщо він уже є — замінимо
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

У цьому прикладі файл "old_name.txt" буде перейменовано на "new_name.txt". Якщо в папці вже лежав файл із такою назвою, він буде перезаписаний.

Перейменування папки

Path oldDir = Path.of("data/old_reports");
Path newDir = Path.of("data/archived_reports");

Files.move(oldDir, newDir);
System.out.println("Папку перейменовано!");

4. Обробка помилок під час копіювання, переміщення й перейменування

Робота з файловою системою — це завжди ризик неочікуваних ситуацій. Ось найчастіші проблеми:

Файл уже існує.
Виняток: FileAlreadyExistsException. Рішення: використовуйте REPLACE_EXISTING, якщо хочете перезаписати.

Файл або папка зайняті іншим процесом.
Виняток: IOException. Наприклад, файл відкрито в іншій програмі.

Немає доступу до файлу або папки.
Виняток: AccessDeniedException. Проблема з правами користувача.

Переміщення між різними файловими системами.
Виняток: AtomicMoveNotSupportedException. Не всі файлові системи підтримують атомарне переміщення.

Цільова папка не існує.
Для копіювання/переміщення переконайтеся, що цільову папку створено заздалегідь!

Приклад обробки помилок

try {
    Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
} catch (FileAlreadyExistsException e) {
    System.out.println("Файл призначення вже існує: " + target);
} catch (AtomicMoveNotSupportedException e) {
    System.out.println("Атомарне переміщення не підтримується: " + e.getMessage());
} catch (IOException e) {
    System.out.println("Помилка під час переміщення: " + e.getMessage());
}

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

Перевірка існування цільового файлу/папки

Перед копіюванням або переміщенням завжди корисно перевірити, чи не зайнятий шлях призначення:

if (Files.exists(target)) {
    System.out.println("Файл вже є, не будемо перезаписувати.");
} else {
    Files.copy(source, target);
}

Використання тимчасових файлів для безпечних операцій

Під час складних операцій (наприклад, оновлення важливих файлів) часто використовують тимчасові файли — спочатку копіюють у тимчасовий файл, а потім замінюють основний:

Path temp = Path.of("data/report.tmp");
Files.copy(source, temp, StandardCopyOption.REPLACE_EXISTING);
Files.move(temp, target, StandardCopyOption.REPLACE_EXISTING);

Такий підхід мінімізує ризик втрати даних у разі збоїв.

Приклад: резервне копіювання файлу перед заміною

Path file = Path.of("data/report.txt");
Path backup = Path.of("data/report_backup.txt");

if (Files.exists(file)) {
    Files.copy(file, backup, StandardCopyOption.REPLACE_EXISTING);
    System.out.println("Резервну копію створено.");
}

6. Таблиця: основні методи та опції

Операція Метод Java NIO Особливості
Копіювання
Files.copy(source, target, ...)
Не копіює вміст папок!
Переміщення
Files.move(source, target, ...)
Можна використовувати для перейменування
Перейменування
Files.move(source, target, ...)
Новий шлях у тій самій директорії
Перезапис
StandardCopyOption.REPLACE_EXISTING
Перезаписує файл/папку призначення
Перевірка
Files.exists(path)
Перевіряє існування файлу/папки

7. Типові помилки при копіюванні, переміщенні й перейменуванні файлів

Помилка № 1: спроба скопіювати файл у неіснуючу папку. Якщо цільову директорію не створено, отримаєте NoSuchFileException. Рішення: створити папку заздалегідь за допомогою Files.createDirectories.

Помилка № 2: спроба скопіювати папку цілком за допомогою Files.copy. Метод скопіює лише «порожню оболонку», а не вміст. Для повного копіювання потрібен рекурсивний обхід.

Помилка № 3: відсутність обробки наявного файлу. Якщо не передати REPLACE_EXISTING, а файл уже є, буде згенеровано виняток. Краще явно обробляти цей випадок.

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

Помилка № 5: переміщення між різними файловими системами. Іноді операція не підтримується «атомарно» й генерується AtomicMoveNotSupportedException. У такому разі використовуйте звичайне переміщення без атомарності.

Помилка № 6: відсутність прав доступу або блокування файлу. Якщо файл відкрито в іншій програмі або немає прав на запис/читання, отримаєте AccessDeniedException або IOException. Завжди обробляйте такі винятки.

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