1. Classe File: come è iniziato tutto
Anche se abbiamo concluso che la classe File è meglio non usarla nei nuovi progetti, esistono comunque molti sistemi legacy in cui viene impiegata. Perciò è importante capirla e saperci lavorare. La classe File è il vecchio modo di rappresentare un file o una directory su disco. Ma non confondete: un oggetto File non è il file stesso, è solo un «puntatore»/passaporto del percorso. Per esempio, l’espressione File f = new File("hello.txt"); non crea il file sul disco — avete semplicemente descritto un percorso.
Come creare un oggetto File?
import java.io.File;
public class FileDemo {
public static void main(String[] args) {
File file = new File("example.txt"); // percorso relativo
File folder = new File("mydir"); // directory
System.out.println("Percorso assoluto: " + file.getAbsolutePath());
System.out.println("Il file esiste? " + file.exists());
System.out.println("È un file? " + file.isFile());
System.out.println("È una directory? " + folder.isDirectory());
}
}
Cosa è importante ricordare:
La creazione di un oggetto File non crea il file sul disco. È solo una «scorciatoia». Per far apparire davvero il file, bisogna avviare esplicitamente la creazione (per esempio, scrivere dei dati o chiamare file.createNewFile()).
Metodi principali della classe File
- exists() — verifica se il file/la directory esiste.
- isFile() — è un file (e non una cartella)?
- isDirectory() — è una directory?
- getAbsolutePath() — ottenere il percorso assoluto.
- length() — dimensione del file in byte.
- getName() — nome del file o della cartella.
- delete() — eliminare file/directory (se vuota).
Esempio: stampiamo le informazioni sul file
File file = new File("example.txt");
System.out.println("Nome: " + file.getName());
System.out.println("Percorso: " + file.getAbsolutePath());
System.out.println("Dimensione: " + file.length() + " byte");
System.out.println("Esiste? " + file.exists());
2. Classe Path: uno sguardo moderno ai file
Path fa parte del nuovo API dei file (NIO.2, da Java 7). È un’astrazione del percorso verso un file/una directory; il percorso può trovarsi non solo su un disco locale, ma anche, ad esempio, all’interno di un archivio ZIP o su una risorsa remota (se esiste il provider appropriato).
Se File è una vecchia mappa cartacea, allora Path è un navigatore GPS.
Come creare un oggetto Path?
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathDemo {
public static void main(String[] args) {
Path path1 = Paths.get("example.txt"); // percorso relativo
Path path2 = Paths.get("folder", "file.txt"); // uniamo le parti del percorso
System.out.println("Percorso 1: " + path1.toAbsolutePath());
System.out.println("Percorso 2: " + path2.toAbsolutePath());
}
}
Vantaggio: non serve preoccuparsi dei separatori. Paths.get sceglierà il formato corretto per il vostro sistema operativo.
Conversione tra File e Path
- File → Path: file.toPath()
- Path → File: path.toFile()
File file = new File("test.txt");
Path path = file.toPath();
Path anotherPath = Paths.get("data.txt");
File anotherFile = anotherPath.toFile();
Lavorare con i percorsi: resolve, relativize, normalize
Concatenazione dei percorsi (resolve)
Path dir = Paths.get("myfolder");
Path file = dir.resolve("notes.txt"); // myfolder/notes.txt
System.out.println(file); // myfolder/notes.txt
Percorso relativo (relativize)
Path pathA = Paths.get("folderA/file1.txt");
Path pathB = Paths.get("folderA/subfolder/file2.txt");
Path relative = pathA.relativize(pathB);
System.out.println(relative); // ../subfolder/file2.txt
Normalizzazione del percorso (normalize)
Path messy = Paths.get("folder/../folder/file.txt");
Path clean = messy.normalize();
System.out.println(clean); // folder/file.txt
Esempio: costruiamo il percorso a un file
Path home = Paths.get(System.getProperty("user.home"));
Path docs = home.resolve("Documents");
Path myFile = docs.resolve("myfile.txt");
System.out.println("Percorso del file: " + myFile.toAbsolutePath());
3. Classe Files: il vostro coltellino svizzero
La classe Files del package java.nio.file è un insieme di metodi statici di utilità per lavorare con file e directory sopra Path. Sa fare praticamente tutto: verificare l’esistenza, creare/eliminare, leggere/scrivere, copiare/spostare, ottenere attributi e attraversare l’albero delle directory.
Metodi principali della classe Files
- Files.exists(path) — verifica se il file/la directory esiste.
- Files.isDirectory(path) — è una directory?
- Files.size(path) — dimensione del file.
- Files.createFile(path) — creare un file.
- Files.createDirectory(path) — creare una directory.
- Files.delete(path) — eliminare file/directory.
- Files.copy(src, dest) — copiare un file.
- Files.move(src, dest) — spostare/rinominare.
- Files.getLastModifiedTime(path) — ora dell’ultima modifica.
- Files.readAllBytes(path) — leggere l’intero file in un array di byte.
- Files.readAllLines(path) — leggere tutte le righe del file di testo.
- Files.write(path, bytes) — scrivere byte su un file.
Esempio: verifichiamo un file
import java.nio.file.*;
public class FilesDemo {
public static void main(String[] args) {
Path path = Paths.get("example.txt");
System.out.println("Il file esiste? " + Files.exists(path));
System.out.println("È una directory? " + Files.isDirectory(path));
if (Files.exists(path)) {
try {
System.out.println("Dimensione del file: " + Files.size(path) + " byte");
} catch (Exception e) {
System.out.println("Errore durante l’ottenimento della dimensione: " + e.getMessage());
}
}
}
}
4. Pratica: creiamo oggetti, stampiamo proprietà
Creiamo oggetti per file e directory
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CompareDemo {
public static void main(String[] args) {
// Metodo vecchio
File oldFile = new File("test.txt");
File oldDir = new File("mydir");
// Metodo nuovo
Path newFile = Paths.get("test.txt");
Path newDir = Paths.get("mydir");
System.out.println("=== File API ===");
System.out.println("File: " + oldFile.getAbsolutePath());
System.out.println("Esiste? " + oldFile.exists());
System.out.println("È un file? " + oldFile.isFile());
System.out.println("È una directory? " + oldDir.isDirectory());
System.out.println("\n=== Path API ===");
System.out.println("File: " + newFile.toAbsolutePath());
System.out.println("Esiste? " + java.nio.file.Files.exists(newFile));
System.out.println("È un file? " + java.nio.file.Files.isRegularFile(newFile));
System.out.println("È una directory? " + java.nio.file.Files.isDirectory(newDir));
}
}
Stampiamo le proprietà del file
import java.nio.file.*;
public class FileProperties {
public static void main(String[] args) {
Path path = Paths.get("test.txt");
System.out.println("Percorso assoluto: " + path.toAbsolutePath());
System.out.println("Nome del file: " + path.getFileName());
System.out.println("Cartella padre: " + path.getParent());
if (Files.exists(path)) {
try {
System.out.println("Dimensione: " + Files.size(path) + " byte");
System.out.println("Ultima modifica: " + Files.getLastModifiedTime(path));
} catch (Exception e) {
System.out.println("Errore durante il recupero delle informazioni: " + e.getMessage());
}
} else {
System.out.println("File non trovato.");
}
}
}
5. Confronto: File vs Path/Files
| Funzionalità | File (java.io) | Path + Files (java.nio.file) |
|---|---|---|
| Rappresentazione del percorso | Solo disco locale | Disco locale, ZIP, risorse di rete |
| Concatenazione dei percorsi | Combinazione manuale con slash | Comodo con resolve |
| Verifica dell’esistenza | exists() | Files.exists(path) |
| Lettura/scrittura del contenuto | No | Sì (Files.readAll..., Files.write) |
| Ottenimento degli attributi | Di base (length(), lastModified()) | Attributi e viste avanzati |
| Compatibilità | Con tutte le versioni di Java | Java 7 e superiori |
| Lavoro con symlink | Limitato | Supporto completo |
In breve: quando usare cosa?
- Per i nuovi progetti — usate Path e Files.
- Per mantenere codice legacy — a volte dovrete lavorare con File.
6. Sfumature utili
Percorsi relativi e assoluti
Un percorso relativo è relativo alla directory di lavoro corrente; un percorso assoluto è il percorso completo a partire dalla radice del file system.
Path relative = Paths.get("data", "file.txt");
Path absolute = relative.toAbsolutePath();
System.out.println("Percorso assoluto: " + absolute);
Portabilità tra piattaforme
Path e Files tengono conto delle peculiarità del sistema operativo (separatori, codifiche ecc.). Non scrivete percorsi a mano del tipo "C:\\folder\\file.txt" — usate Paths.get e resolve.
Conversione tra File e Path
Se avete del codice vecchio che usa File, passare al nuovo API è semplice:
File legacy = new File("legacy.txt");
Path modern = legacy.toPath();
if (Files.exists(modern)) {
// Ora si possono usare tutte le funzionalità di NIO.2
}
Verifica dell’esistenza di un file
Path path = Paths.get("notes.txt");
if (Files.exists(path)) {
System.out.println("File trovato!");
} else {
System.out.println("Il file non esiste.");
}
7. Mini‑pratica: creiamo e verifichiamo file e directory
import java.nio.file.*;
public class MiniPractice {
public static void main(String[] args) throws Exception {
Path dir = Paths.get("demo_dir");
Path file = dir.resolve("hello.txt");
// Creiamo la directory se non esiste
if (!Files.exists(dir)) {
Files.createDirectory(dir);
System.out.println("Directory creata: " + dir.toAbsolutePath());
}
// Creiamo il file se non esiste
if (!Files.exists(file)) {
Files.createFile(file);
System.out.println("File creato: " + file.toAbsolutePath());
}
// Stampiamo le proprietà
System.out.println("Il file esiste? " + Files.exists(file));
System.out.println("È un file? " + Files.isRegularFile(file));
System.out.println("Dimensione: " + Files.size(file) + " byte");
// Eliminiamo file e directory (opzionale)
Files.delete(file);
Files.delete(dir);
System.out.println("File e directory eliminati.");
}
}
8. Errori tipici nel lavoro con File/Path/Files
Errore n. 1: confusione tra File e Path. Molti principianti cercano di usare i metodi Files con un oggetto File. Ricordate: Files.* lavora con Path. Se avete un File, prima fate file.toPath().
Errore n. 2: aspettarsi che la creazione di un oggetto File o Path crei il file. Un oggetto percorso è una scorciatoia, non un file reale. Per creare usate Files.createFile(path) oppure scrivete dei dati.
Errore n. 3: costruire i percorsi manualmente come stringa. Non scrivete "folder/file.txt" o "folder\\file.txt". Usate Paths.get(...) e resolve(...). È più sicuro e multipiattaforma.
Errore n. 4: ignorare le eccezioni. Le operazioni sui file generano IOException e altre eccezioni. Gestitele con try-catch oppure propagate più in alto (throws).
Errore n. 5: controllare con File.exists(), poi lavorare con Path. Cercate di mantenere uno stile coerente: se avete iniziato con Path, usate Files.exists(path) e gli altri metodi di Files.
GO TO FULL VERSION