1. Introduzione
Nella programmazione quasi sempre bisogna lavorare con i file. Esempi noti a tutti: salvare il testo di una nota, lo stato di avanzamento in un gioco, copiare un'immagine oppure leggere le impostazioni da un file di configurazione.
In Java esistono strumenti moderni e comodi: Path e Files del package java.nio.file. Consentono, con poche righe di codice, di aprire un file, leggerne il contenuto, scrivere testo o persino copiare un'immagine.
Percorso del file (Path)
Un file si trova sempre da qualche parte sul disco e, per accedervi, è necessario specificare il percorso. A questo scopo in Java esiste la classe Path, e si può creare un nuovo oggetto con il metodo Path.of().
Path path = Path.of("hello.txt"); // percorso relativo
Path absPath = Path.of("C:/Users/Me/image.png"); // percorso assoluto (Windows)
Spiegazione:
- Un percorso relativo cerca il file nella cartella corrente del progetto (ad esempio, "hello.txt").
- Un percorso assoluto indica l'indirizzo completo: unità, cartelle e nome del file.
2. Lavorare con i file di testo
Dal punto di vista di Java, tutti i file si dividono in 2 tipi — testuali e binari. Se il contenuto può essere rappresentato come testo comprensibile a una persona, è un file di testo. In tutti gli altri casi si tratta semplicemente di una sequenza di byte (file binario).
Scrivere testo su file — writeString
Per scrivere una stringa in un file, si utilizza il metodo writeString.
Path p = Path.of("hello.txt");
Files.writeString(p, "Ciao, file!");
Che cosa è successo qui:
- creiamo un oggetto Path che punta a "hello.txt";
- con il metodo writeString ci scriviamo la stringa;
- se il file non esiste, verrà creato automaticamente.
In questo modo è facile salvare note o messaggi in un file di testo.
Leggere testo da file — readString
Il metodo readString consente di caricare l'intero file direttamente in una stringa.
Path p = Path.of("hello.txt");
String content = Files.readString(p);
System.out.println(content);
Ora la variabile content contiene il contenuto del file. È comodo per file di piccole dimensioni: config, testi, documenti JSON.
3. Lavorare con i file binari
Non tutti i file sono costituiti da testo. Immagini, musica, archivi — sono insiemi di byte. Per lavorarci ci sono i metodi write e readAllBytes.
Scrivere byte su file — write
Il metodo write() consente di scrivere su file un array di byte. Lo si chiama anche buffer (byte buffer).
byte[] data = {65, 66, 67, 68}; // caratteri A B C D
Files.write(Path.of("letters.bin"), data);
Qui abbiamo scritto su file un array di byte. Se si apre il file come testo, all'interno ci saranno le lettere "ABCD".
Leggere byte — readAllBytes
Per ottenere il contenuto del file come array di byte, si usa il metodo readAllBytes.
byte[] buffer = Files.readAllBytes(Path.of("letters.bin"));
// stampiamo sullo schermo l'array di byte letto
for (byte b : buffer)
{
System.out.print((char)b + " ");
}
Sullo schermo apparirà:
A B C D
Questo approccio si usa per lavorare con qualsiasi file binario — immagini, documenti, musica.
4. Scenari comuni di lavoro con i file
Lo scenario più comune quando si lavora con i file è probabilmente la copia di un file.
Copiare file
Per copiare un file, si può semplicemente leggerlo in un array di byte e scriverlo in un altro file.
Path in = Path.of("logo.png");
Path out = Path.of("logo_copy.png");
byte[] bytes = Files.readAllBytes(in);
Files.write(out, bytes);
In questo modo è possibile copiare immagini, documenti e qualsiasi altro file senza preoccuparsi del loro formato.
Verifica di esistenza e dimensione
Talvolta è necessario assicurarsi che un file esista e conoscerne la dimensione. A tal fine ci sono i metodi exists e size.
Path p = Path.of("hello.txt");
if (Files.exists(p))
{
long size = Files.size(p);
System.out.println("File trovato, dimensione: " + size + " byte");
}
else
{
System.out.println("File non trovato!");
}
Questo è utile per la diagnostica: saprete con certezza se state lavorando con il file giusto.
5. Eccezioni
Il lavoro con i file può terminare con un errore: il file non esiste, mancano i permessi, il disco è pieno oppure il file è occupato da un altro programma. Perciò è necessario racchiudere le operazioni su disco in try-catch o, in alternativa, propagare le eccezioni verso l'esterno con throws.
try
{
String content = Files.readString(Path.of("hello.txt"));
System.out.println(content);
}
catch (IOException e)
{
System.out.println("Errore durante la lettura: " + e.getMessage());
}
In questo modo il programma non si “bloccherà”, ma informerà correttamente l'utente di ciò che è accaduto. Se necessario, è possibile propagare l'eccezione IOException più in alto nello stack da un metodo usando la parola chiave throws.
GO TO FULL VERSION