CodeGym /Corsi /JAVA 25 SELF /Copia e spostamento di file e cartelle

Copia e spostamento di file e cartelle

JAVA 25 SELF
Livello 40, Lezione 1
Disponibile

1. Copia dei file

Metodo Files.copy: sintassi di base

In Java per copiare file e cartelle si usa il metodo statico Files.copy del package java.nio.file. Lo abbiamo già incontrato, ma ora lo studieremo più in dettaglio. La sintassi di base di Files.copy:

Files.copy(Path source, Path target, CopyOption... options)
  • source — percorso al file o alla cartella di origine.
  • target — percorso di destinazione della copia.
  • options — opzioni aggiuntive (per esempio, consentire la sovrascrittura).

Esempio base

Copiamo il file "input.txt" dalla directory corrente nella cartella "backup" con il nome "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("File copiato!");
    }
}

Punti importanti:

  • Se il file di destinazione esiste già, verrà lanciata l'eccezione FileAlreadyExistsException.
  • Se la cartella "backup" non esiste, il metodo genererà un errore — la cartella deve essere creata in anticipo!

Copia con sovrascrittura

Per consentire la sovrascrittura del file, usa l'opzione StandardCopyOption.REPLACE_EXISTING:

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

Tabella: principali opzioni di copia

Opzione Descrizione
StandardCopyOption.REPLACE_EXISTING
Sovrascrive il file se esiste già
StandardCopyOption.COPY_ATTRIBUTES
Copia gli attributi (data di creazione ecc.)
StandardCopyOption.ATOMIC_MOVE
Spostamento atomico (usato solo con move)

Copia di un file in un'altra cartella

Prima di copiare un file, assicurati che la cartella di destinazione esista:

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

Copia di directory: insidia

Il metodo Files.copy sa copiare le cartelle solo come «guscio vuoto» — il contenuto (file e sottocartelle) non viene copiato! Se provi a copiare una cartella con dei file, otterrai solo una directory vuota. Per copiare intere directory con il contenuto è necessario un attraversamento ricorsivo e la copia manuale di ogni file (torneremo su questo nelle prossime lezioni).

Esempio: copiare un file da una cartella a un'altra

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

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

Gestione degli errori durante la copia

La copia può fallire per vari motivi: nessun accesso, file occupato, spazio insufficiente, file già esistente, ecc. È meglio usare sempre try-catch:

try {
    Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
    System.out.println("Copia riuscita!");
} catch (FileAlreadyExistsException e) {
    System.out.println("Il file esiste già: " + target);
} catch (IOException e) {
    System.out.println("Errore di I/O: " + e.getMessage());
}

2. Spostamento di file e cartelle

Metodo Files.move: sintassi

Lo spostamento di file e cartelle si esegue con il metodo:

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

Dove source — percorso del file (da dove lo spostiamo), target — dove vogliamo posizionare il file o la cartella, options — impostazioni aggiuntive (per esempio, la sostituzione di un file esistente).

A proposito, lo spostamento non è solo il «trasferimento» del file, ma anche un modo per rinominarlo (se cambia solo il nome). E se nella cartella di destinazione esiste già un file con quel nome, verrà lanciata un'eccezione se non specifichi l'opzione REPLACE_EXISTING.

Esempio: spostamento di un file in un'altra cartella

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

Files.move(source, target);
System.out.println("File spostato!");

Spostamento con sostituzione del file esistente

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

Spostamento di una cartella

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

Files.move(oldDir, newDir);

L'intera cartella, inclusi i file e le sottocartelle, verrà spostata nella nuova posizione.
Ma se nella cartella di destinazione esiste già una cartella con lo stesso nome — otterrai un errore.

Spostamento tra file system diversi

Se sposti un file tra dischi diversi (ad esempio da "C:" a "D:"), sotto il cofano avverrà una copia seguita dall'eliminazione del file originale. Se l'operazione non è supportata come atomica, può essere lanciata l'eccezione AtomicMoveNotSupportedException.

Differenza tra move e copy

  • copy — il file/la cartella originale rimane al suo posto, appare una copia.
  • move — il file/la cartella originale scompare, rimane solo il nuovo elemento.

3. Rinomina di file e cartelle

In Java non esiste un metodo separato «rinomina file». La ridenominazione è un caso particolare di spostamento: si specifica un nuovo percorso con un nome diverso nella stessa directory.

Esempio: rinominare un file

Supponiamo di avere il file "report.txt" e di volerlo rinominare in "report_old.txt" nella stessa cartella:

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("File rinominato!");

Aspetti importanti

Se nella directory di destinazione esiste già un file o una cartella con il nome che indichi, il metodo lancerà un'eccezione. Per aggirare il limite e consentire la sostituzione, puoi usare l'opzione StandardCopyOption.REPLACE_EXISTING.

Esempio:

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

// Rinominiamo il file; se esiste già — lo sostituiamo
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

In questo esempio, il file "old_name.txt" verrà rinominato in "new_name.txt". Se nella cartella era già presente un file con quel nome, verrà sovrascritto.

Rinominare una cartella

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

Files.move(oldDir, newDir);
System.out.println("Cartella rinominata!");

4. Gestione degli errori durante copia, spostamento e rinomina

Lavorare con il file system comporta sempre il rischio di situazioni impreviste. Ecco i problemi più comuni:

Il file esiste già.
Eccezione: FileAlreadyExistsException. Soluzione: usa REPLACE_EXISTING se vuoi sovrascrivere.

File o cartella occupati da un altro processo.
Eccezione: IOException. Ad esempio, il file è aperto in un altro programma.

Nessun accesso al file o alla cartella.
Eccezione: AccessDeniedException. Problema di permessi dell'utente.

Spostamento tra file system diversi.
Eccezione: AtomicMoveNotSupportedException. Non tutti i file system supportano lo spostamento atomico.

La cartella di destinazione non esiste.
Per copiare/spostare assicurati che la cartella di destinazione sia stata creata in anticipo!

Esempio di gestione degli errori

try {
    Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
} catch (FileAlreadyExistsException e) {
    System.out.println("Il file di destinazione esiste già: " + target);
} catch (AtomicMoveNotSupportedException e) {
    System.out.println("Spostamento atomico non supportato: " + e.getMessage());
} catch (IOException e) {
    System.out.println("Errore durante lo spostamento: " + e.getMessage());
}

5. Raccomandazioni pratiche

Verifica dell'esistenza del file/cartella di destinazione

Prima di copiare o spostare è sempre utile verificare se il percorso di destinazione è già occupato:

if (Files.exists(target)) {
    System.out.println("Il file esiste già, non lo sovrascriviamo.");
} else {
    Files.copy(source, target);
}

Uso di file temporanei per operazioni sicure

Nelle operazioni complesse (ad esempio l'aggiornamento di file importanti) spesso si usano file temporanei: prima si copia in un file temporaneo, poi si sostituisce l'originale:

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

Questo approccio riduce al minimo il rischio di perdita di dati in caso di guasti.

Esempio: creare un backup del file prima della sostituzione

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("Backup creato.");
}

6. Tabella: metodi e opzioni principali

Operazione Metodo Java NIO Particolarità
Copia
Files.copy(source, target, ...)
Non copia il contenuto delle cartelle!
Spostamento
Files.move(source, target, ...)
Può essere usato per la rinomina
Rinomina
Files.move(source, target, ...)
Nuovo percorso nella stessa directory
Sovrascrittura
StandardCopyOption.REPLACE_EXISTING
Sovrascrive il file/la cartella di destinazione
Verifica
Files.exists(path)
Verifica l'esistenza del file/della cartella

7. Errori tipici durante la copia, lo spostamento e la rinomina dei file

Errore n. 1: tentativo di copiare un file in una cartella inesistente. Se la directory di destinazione non è stata creata, otterrai NoSuchFileException. Soluzione: creare la cartella in anticipo con Files.createDirectories.

Errore n. 2: tentativo di copiare un'intera cartella con Files.copy. Il metodo copierà solo il «guscio vuoto», non il contenuto. Per una copia completa serve una traversata ricorsiva.

Errore n. 3: mancata gestione del file esistente. Se non passi REPLACE_EXISTING e il file è già presente, verrà lanciata un'eccezione. È meglio gestire esplicitamente questo caso.

Errore n. 4: tentativo di rinominare un file quando esiste già un file con il nuovo nome. Analogamente, otterrai FileAlreadyExistsException. Prima di rinominare puoi verificare la presenza del file.

Errore n. 5: spostamento tra file system diversi. A volte l'operazione non è supportata in modo «atomico» e viene lanciata AtomicMoveNotSupportedException. In tal caso usa uno spostamento normale senza atomicità.

Errore n. 6: mancanza di permessi o blocco del file. Se il file è aperto in un altro programma o non ci sono permessi di lettura/scrittura, otterrai AccessDeniedException o IOException. Gestisci sempre tali eccezioni.

1
Compito
JAVA 25 SELF, livello 40, lezione 1
Bloccato
Spostamento del report più recente nell'archivio 📦
Spostamento del report più recente nell'archivio 📦
1
Compito
JAVA 25 SELF, livello 40, lezione 1
Bloccato
Rinominare un documento obsoleto 📝
Rinominare un documento obsoleto 📝
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION