CodeGym /Kursy /JAVA 25 SELF /Kopiowanie i przenoszenie plików i folderów

Kopiowanie i przenoszenie plików i folderów

JAVA 25 SELF
Poziom 40, Lekcja 1
Dostępny

1. Kopiowanie plików

Metoda Files.copy: podstawowa składnia

W Javie do kopiowania plików i folderów używa się metody statycznej Files.copy z pakietu java.nio.file. Już się z nią spotkaliśmy, ale teraz omówimy ją dokładniej. Podstawowa składnia Files.copy:

Files.copy(Path source, Path target, CopyOption... options)
  • source — ścieżka do pliku lub folderu źródłowego.
  • target — ścieżka docelowa, dokąd kopiować.
  • options — dodatkowe opcje (np. zezwolenie na nadpisanie).

Najprostszy przykład

Skopiujmy plik "input.txt" z bieżącego katalogu do folderu "backup" pod nazwą "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("Plik został skopiowany!");
    }
}

Ważne uwagi:

  • Jeśli plik docelowy już istnieje, zostanie zgłoszony wyjątek FileAlreadyExistsException.
  • Jeśli folder "backup" nie istnieje, metoda zgłosi błąd — folder musi zostać utworzony wcześniej!

Kopiowanie z nadpisaniem

Aby zezwolić na nadpisanie pliku, użyj opcji StandardCopyOption.REPLACE_EXISTING:

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

Tabela: najważniejsze opcje kopiowania

Opcja Opis
StandardCopyOption.REPLACE_EXISTING
Nadpisuje plik, jeśli już istnieje
StandardCopyOption.COPY_ATTRIBUTES
Kopiuje atrybuty (data utworzenia itp.)
StandardCopyOption.ATOMIC_MOVE
Przeniesienie atomowe (używane tylko z move)

Kopiowanie pliku do innego folderu

Przed skopiowaniem pliku upewnij się, że folder docelowy istnieje:

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

Kopiowanie katalogów: pułapka

Metoda Files.copy potrafi kopiować foldery jedynie jako „pustą skorupę” — zawartość (pliki i podfoldery) nie jest kopiowana! Jeśli spróbujesz skopiować folder z plikami, otrzymasz tylko pusty katalog. Aby skopiować całe katalogi wraz z zawartością, potrzebny jest rekursywny przebieg i ręczne kopiowanie każdego pliku (wrócimy do tego w kolejnych wykładach).

Przykład: kopiujemy plik z jednego folderu do innego

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

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

Obsługa błędów przy kopiowaniu

Kopiowanie może się nie powieść z różnych powodów: brak dostępu, plik zajęty, za mało miejsca, plik już istnieje itd. Najlepiej zawsze używać try-catch:

try {
    Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
    System.out.println("Kopiowanie zakończone powodzeniem!");
} catch (FileAlreadyExistsException e) {
    System.out.println("Plik już istnieje: " + target);
} catch (IOException e) {
    System.out.println("Błąd wejścia/wyjścia: " + e.getMessage());
}

2. Przenoszenie plików i folderów

Metoda Files.move: składnia

Przenoszenie plików i folderów wykonuje się za pomocą metody:

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

Gdzie source — ścieżka do pliku (skąd przenosimy), target — dokąd chcemy umieścić plik lub folder, options — dodatkowe ustawienia (np. zastąpienie istniejącego pliku).

Przy okazji, przeniesienie to nie tylko „przeprowadzka” pliku, lecz także sposób na zmianę nazwy (jeśli zmienia się tylko nazwa). A jeśli w folderze docelowym istnieje już plik o tej nazwie, zostanie zgłoszony wyjątek, jeśli nie podasz opcji REPLACE_EXISTING.

Przykład: przeniesienie pliku do innego folderu

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

Files.move(source, target);
System.out.println("Plik przeniesiono!");

Przenoszenie z zastąpieniem istniejącego pliku

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

Przenoszenie folderu

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

Files.move(oldDir, newDir);

Cały folder, łącznie z plikami i podfolderami, trafi w nowe miejsce.
Ale jeśli w folderze docelowym istnieje już folder o takiej nazwie — otrzymasz błąd.

Przenoszenie między różnymi systemami plików

Jeśli przenosisz plik między różnymi dyskami (np. z "C:" na "D:"), pod spodem nastąpi skopiowanie, a następnie usunięcie pliku źródłowego. Jeśli operacja nie jest wspierana jako atomowa, może zostać zgłoszony wyjątek AtomicMoveNotSupportedException.

Różnica między move a copy

  • copy — plik/folder źródłowy pozostaje na miejscu, pojawia się kopia.
  • move — plik/folder źródłowy znika, pozostaje tylko nowy egzemplarz.

3. Zmienianie nazw plików i folderów

W Javie nie ma osobnej metody „zmień nazwę pliku”. Zmiana nazwy to szczególny przypadek przeniesienia: podajesz nową ścieżkę z inną nazwą w tym samym katalogu.

Przykład: zmiana nazwy pliku

Załóżmy, że mamy plik "report.txt" i chcemy zmienić jego nazwę na "report_old.txt" w tym samym folderze:

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("Zmieniono nazwę pliku!");

Ważne szczegóły

Jeśli w katalogu docelowym istnieje już plik lub folder o podanej nazwie, metoda zgłosi wyjątek. Aby obejść to ograniczenie i zezwolić na zastąpienie, można użyć opcji StandardCopyOption.REPLACE_EXISTING.

Przykład:

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

// Zmieńmy nazwę pliku; jeśli już istnieje — zastąpimy go
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

W tym przykładzie plik "old_name.txt" zostanie przemianowany na "new_name.txt". Jeśli w folderze istniał już plik o takiej nazwie, zostanie on nadpisany.

Zmiana nazwy folderu

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

Files.move(oldDir, newDir);
System.out.println("Zmieniono nazwę folderu!");

4. Obsługa błędów przy kopiowaniu, przenoszeniu i zmianie nazw

Praca z systemem plików zawsze wiąże się z ryzykiem nieoczekiwanych sytuacji. Oto najczęstsze problemy:

Plik już istnieje.
Wyjątek: FileAlreadyExistsException. Rozwiązanie: użyj REPLACE_EXISTING, jeśli chcesz nadpisać.

Plik lub folder jest zajęty przez inny proces.
Wyjątek: IOException. Na przykład plik jest otwarty w innym programie.

Brak dostępu do pliku lub folderu.
Wyjątek: AccessDeniedException. Problem z uprawnieniami użytkownika.

Przenoszenie między różnymi systemami plików.
Wyjątek: AtomicMoveNotSupportedException. Nie wszystkie systemy plików obsługują przenoszenie atomowe.

Folder docelowy nie istnieje.
Przed kopiowaniem/przenoszeniem upewnij się, że folder docelowy został utworzony wcześniej!

Przykład obsługi błędów

try {
    Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
} catch (FileAlreadyExistsException e) {
    System.out.println("Plik docelowy już istnieje: " + target);
} catch (AtomicMoveNotSupportedException e) {
    System.out.println("Przenoszenie atomowe nie jest obsługiwane: " + e.getMessage());
} catch (IOException e) {
    System.out.println("Błąd podczas przenoszenia: " + e.getMessage());
}

5. Praktyczne wskazówki

Sprawdzanie istnienia pliku/folderu docelowego

Przed kopiowaniem lub przenoszeniem zawsze warto sprawdzić, czy ścieżka docelowa nie jest zajęta:

if (Files.exists(target)) {
    System.out.println("Plik już istnieje, nie będziemy nadpisywać.");
} else {
    Files.copy(source, target);
}

Użycie plików tymczasowych dla bezpiecznych operacji

Przy złożonych operacjach (np. aktualizacja ważnych plików) często używa się plików tymczasowych — najpierw kopiuje się do pliku tymczasowego, a potem zastępuje plik główny:

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

Takie podejście minimalizuje ryzyko utraty danych przy awariach.

Przykład: wykonanie kopii zapasowej pliku przed zastąpieniem

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("Utworzono kopię zapasową.");
}

6. Tabela: najważniejsze metody i opcje

Operacja Metoda Java NIO Uwagi
Kopiowanie
Files.copy(source, target, ...)
Nie kopiuje zawartości folderów!
Przenoszenie
Files.move(source, target, ...)
Można użyć do zmiany nazwy
Zmiana nazwy
Files.move(source, target, ...)
Nowa ścieżka w tym samym katalogu
Nadpisanie
StandardCopyOption.REPLACE_EXISTING
Nadpisuje plik/folder docelowy
Sprawdzenie
Files.exists(path)
Sprawdza istnienie pliku/folderu

7. Typowe błędy przy kopiowaniu, przenoszeniu i zmianie nazw plików

Błąd nr 1: próba skopiowania pliku do nieistniejącego folderu. Jeśli katalog docelowy nie został utworzony, otrzymasz NoSuchFileException. Rozwiązanie: utworzyć folder wcześniej za pomocą Files.createDirectories.

Błąd nr 2: próba skopiowania całego folderu za pomocą Files.copy. Metoda skopiuje tylko „pustą skorupę”, a nie zawartość. Do pełnego kopiowania potrzebny jest rekursywny przebieg.

Błąd nr 3: brak obsługi istniejącego pliku. Jeśli nie przekażesz REPLACE_EXISTING, a plik już istnieje, zostanie zgłoszony wyjątek. Lepiej jawnie obsłużyć ten przypadek.

Błąd nr 4: próba zmiany nazwy, gdy plik o nowej nazwie już istnieje. Podobnie, otrzymasz FileAlreadyExistsException. Przed zmianą nazwy można sprawdzić istnienie pliku.

Błąd nr 5: przenoszenie między różnymi systemami plików. Czasem operacja nie jest wspierana „atomowo” i zgłaszany jest AtomicMoveNotSupportedException. W takim przypadku użyj zwykłego przeniesienia bez atomowości.

Błąd nr 6: brak uprawnień lub blokada pliku. Jeśli plik jest otwarty w innym programie lub brakuje praw do zapisu/odczytu, otrzymasz AccessDeniedException lub IOException. Zawsze obsługuj takie wyjątki.

1
Zadanie
JAVA 25 SELF, poziom 40, lekcja 1
Niedostępne
Przeniesienie świeżego raportu do archiwum 📦
Przeniesienie świeżego raportu do archiwum 📦
1
Zadanie
JAVA 25 SELF, poziom 40, lekcja 1
Niedostępne
Zmiana nazwy przestarzałego dokumentu 📝
Zmiana nazwy przestarzałego dokumentu 📝
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION