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);
Таблиця: основні опції копіювання
| Опція | Опис |
|---|---|
|
Перезаписувати файл, якщо він уже існує |
|
Копіювати атрибути (дата створення тощо) |
|
Атомарне переміщення (використовується лише з 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 | Особливості |
|---|---|---|
| Копіювання | |
Не копіює вміст папок! |
| Переміщення | |
Можна використовувати для перейменування |
| Перейменування | |
Новий шлях у тій самій директорії |
| Перезапис | |
Перезаписує файл/папку призначення |
| Перевірка | |
Перевіряє існування файлу/папки |
7. Типові помилки при копіюванні, переміщенні й перейменуванні файлів
Помилка № 1: спроба скопіювати файл у неіснуючу папку. Якщо цільову директорію не створено, отримаєте NoSuchFileException. Рішення: створити папку заздалегідь за допомогою Files.createDirectories.
Помилка № 2: спроба скопіювати папку цілком за допомогою Files.copy. Метод скопіює лише «порожню оболонку», а не вміст. Для повного копіювання потрібен рекурсивний обхід.
Помилка № 3: відсутність обробки наявного файлу. Якщо не передати REPLACE_EXISTING, а файл уже є, буде згенеровано виняток. Краще явно обробляти цей випадок.
Помилка № 4: спроба перейменувати файл, коли файл із новою назвою вже існує. Аналогічно, отримаєте FileAlreadyExistsException. Перед перейменуванням можна перевірити наявність файлу.
Помилка № 5: переміщення між різними файловими системами. Іноді операція не підтримується «атомарно» й генерується AtomicMoveNotSupportedException. У такому разі використовуйте звичайне переміщення без атомарності.
Помилка № 6: відсутність прав доступу або блокування файлу. Якщо файл відкрито в іншій програмі або немає прав на запис/читання, отримаєте AccessDeniedException або IOException. Завжди обробляйте такі винятки.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ