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 |
|---|---|
|
Sovrascrive il file se esiste già |
|
Copia gli attributi (data di creazione ecc.) |
|
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 | |
Non copia il contenuto delle cartelle! |
| Spostamento | |
Può essere usato per la rinomina |
| Rinomina | |
Nuovo percorso nella stessa directory |
| Sovrascrittura | |
Sovrascrive il file/la cartella di destinazione |
| Verifica | |
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.
GO TO FULL VERSION