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. Всегда обрабатывайте такие исключения.

1
Задача
JAVA 25 SELF, 40 уровень, 1 лекция
Недоступна
Перемещение свежего отчёта в архив 📦
Перемещение свежего отчёта в архив 📦
1
Задача
JAVA 25 SELF, 40 уровень, 1 лекция
Недоступна
Переименование устаревшего документа 📝
Переименование устаревшего документа 📝
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ