1. Lettura degli attributi di base: BasicFileAttributes
Quando parliamo di un file o di una cartella, non intendiamo solo il suo nome o la sua dimensione. Ogni file ha un «passaporto» — un insieme di attributi che contiene:
- Data di creazione
- Data dell’ultima modifica
- Data dell’ultimo accesso
- Dimensione
- Permessi di accesso (chi può leggere, scrivere, eseguire)
- Informazioni sul proprietario (su Unix)
- Flag «nascosto», «sola lettura» e altro
In Java, per lavorare con questi attributi c’è un’API comoda e potente nel pacchetto java.nio.file.attribute. Non serve scrivere codice dipendente dalla piattaforma: tutto il necessario è nella libreria standard.
Per cominciare — importiamo le classi necessarie:
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;
Come ottenere gli attributi di base di un file?
Usiamo il metodo Files.readAttributes:
Path path = Paths.get("example.txt");
try {
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Creato: " + attrs.creationTime());
System.out.println("Modificato: " + attrs.lastModifiedTime());
System.out.println("Ultimo accesso: " + attrs.lastAccessTime());
System.out.println("Dimensione: " + attrs.size());
System.out.println("È una directory? " + attrs.isDirectory());
System.out.println("È un file? " + attrs.isRegularFile());
System.out.println("È un collegamento simbolico? " + attrs.isSymbolicLink());
} catch (IOException e) {
System.out.println("Errore durante la lettura degli attributi: " + e.getMessage());
}
Immagina di essere un ispettore e di andare a controllare un appartamento. Non ti limiti a guardare se c’è la porta (il file esiste), ma chiedi anche agli inquilini: «Quando è stato costruito l’edificio? Quando è stata fatta l’ultima ristrutturazione? Chi è il proprietario?».
In breve sulle proprietà di BasicFileAttributes
| Proprietà | Cosa restituisce? |
|---|---|
|
Data e ora di creazione del file/della cartella |
|
Data e ora dell’ultima modifica |
|
Data e ora dell’ultimo accesso |
|
Dimensione del file (in byte) |
|
È una directory? |
|
È un file regolare? |
|
È un collegamento simbolico? |
2. Attributi avanzati: POSIX e DOS
Attributi POSIX (Linux, macOS e altri sistemi Unix-like)
Se lavori su un sistema Unix, puoi ottenere informazioni avanzate: permessi di accesso, proprietario, gruppo.
try {
PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
System.out.println("Proprietario: " + posixAttrs.owner().getName());
System.out.println("Gruppo: " + posixAttrs.group().getName());
System.out.println("Permessi: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
System.out.println("Gli attributi POSIX non sono supportati su questo sistema operativo.");
} catch (IOException e) {
System.out.println("Errore durante la lettura degli attributi POSIX: " + e.getMessage());
}
Nota: Su Windows questo codice lancerà UnsupportedOperationException — è normale.
Attributi DOS (Windows)
Su Windows puoi lavorare con i flag «sola lettura», «nascosto», «archivio», «di sistema»:
try {
DosFileAttributes dosAttrs = Files.readAttributes(path, DosFileAttributes.class);
System.out.println("Nascosto: " + dosAttrs.isHidden());
System.out.println("Sola lettura: " + dosAttrs.isReadOnly());
System.out.println("Di sistema: " + dosAttrs.isSystem());
System.out.println("Archivio: " + dosAttrs.isArchive());
} catch (UnsupportedOperationException e) {
System.out.println("Gli attributi DOS non sono supportati su questo sistema operativo.");
} catch (IOException e) {
System.out.println("Errore durante la lettura degli attributi DOS: " + e.getMessage());
}
3. Modifica degli attributi dei file
Leggere i passaporti altrui è una cosa, ma cambiare la data di nascita o il cognome è un’altra! In Java possiamo modificare gli attributi dei file (ovviamente con i permessi necessari).
Modifica dell’ora dell’ultima modifica
import java.nio.file.attribute.FileTime;
Path file = Paths.get("example.txt");
try {
FileTime newTime = FileTime.fromMillis(System.currentTimeMillis() - 24 * 60 * 60 * 1000); // meno 1 giorno
Files.setLastModifiedTime(file, newTime);
System.out.println("L’ora dell’ultima modifica è stata cambiata!");
} catch (IOException e) {
System.out.println("Errore durante la modifica dell’ora: " + e.getMessage());
}
Modifica dei permessi di accesso (POSIX)
Solo per sistemi Unix! Per esempio, rendere il file eseguibile per tutti:
try {
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-xr-x");
Files.setPosixFilePermissions(file, perms);
System.out.println("Permessi modificati!");
} catch (UnsupportedOperationException e) {
System.out.println("I permessi POSIX non sono supportati su questo sistema operativo.");
} catch (IOException e) {
System.out.println("Errore durante la modifica dei permessi: " + e.getMessage());
}
Spiegazione della stringa "rwxr-xr-x":
- r — read (lettura)
- w — write (scrittura)
- x — execute (esecuzione)
- Il primo blocco di 3 caratteri — proprietario, il secondo — gruppo, il terzo — altri.
Modifica dello stato nascosto/sola lettura (attributi DOS, Windows)
Rendere il file nascosto:
try {
Files.setAttribute(file, "dos:hidden", true);
System.out.println("Il file è diventato nascosto (Windows)!");
} catch (UnsupportedOperationException e) {
System.out.println("Gli attributi DOS non sono supportati su questo sistema operativo.");
} catch (IOException e) {
System.out.println("Errore durante la modifica dell’attributo: " + e.getMessage());
}
Rendere il file «sola lettura»:
try {
Files.setAttribute(file, "dos:readonly", true);
System.out.println("Il file ora è a sola lettura (Windows)!");
} catch (UnsupportedOperationException e) {
System.out.println("Gli attributi DOS non sono supportati su questo sistema operativo.");
} catch (IOException e) {
System.out.println("Errore durante la modifica dell’attributo: " + e.getMessage());
}
4. Verifica dei permessi di accesso
A volte è importante verificare rapidamente se è possibile aprire un file per lettura, scrittura o esecuzione:
Path file = Paths.get("example.txt");
System.out.println("Lettura consentita: " + Files.isReadable(file));
System.out.println("Scrittura consentita: " + Files.isWritable(file));
System.out.println("Esecuzione consentita: " + Files.isExecutable(file));
Questo funziona allo stesso modo su tutte le piattaforme, anche se il comportamento reale dipende dal sistema operativo e dalle impostazioni di sicurezza.
5. Pratica: stampa di informazioni dettagliate su un file
Scriviamo un mini‑programma che, dato il percorso di un file, mostri il massimo di informazioni e provi a modificare alcuni attributi.
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;
import java.io.IOException;
public class FileAttributesDemo {
public static void main(String[] args) throws IOException {
Path path = Paths.get("example.txt");
if (!Files.exists(path)) {
System.out.println("File non trovato!");
return;
}
// Attributi di base
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Nome: " + path.getFileName());
System.out.println("Percorso: " + path.toAbsolutePath());
System.out.println("Dimensione: " + attrs.size() + " byte");
System.out.println("Creato: " + attrs.creationTime());
System.out.println("Modificato: " + attrs.lastModifiedTime());
System.out.println("Ultimo accesso: " + attrs.lastAccessTime());
System.out.println("È una directory? " + attrs.isDirectory());
System.out.println("È un file? " + attrs.isRegularFile());
// Verifica dei permessi di accesso
System.out.println("Lettura consentita: " + Files.isReadable(path));
System.out.println("Scrittura consentita: " + Files.isWritable(path));
System.out.println("Esecuzione consentita: " + Files.isExecutable(path));
// Proviamo a modificare l’ora di modifica
FileTime now = FileTime.fromMillis(System.currentTimeMillis());
Files.setLastModifiedTime(path, now);
System.out.println("Ora dell’ultima modifica aggiornata!");
// Proviamo a rendere il file nascosto (se supportato)
try {
Files.setAttribute(path, "dos:hidden", true);
System.out.println("Il file è diventato nascosto (se supportato dal sistema operativo).");
} catch (UnsupportedOperationException e) {
System.out.println("I file nascosti non sono supportati su questo sistema operativo.");
}
// Proviamo a stampare i permessi POSIX (se supportato)
try {
PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
System.out.println("Proprietario: " + posixAttrs.owner().getName());
System.out.println("Permessi: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
System.out.println("Gli attributi POSIX non sono supportati su questo sistema operativo.");
}
}
}
6. Dettagli utili
Differenze cross‑platform e consigli
- Non tutti gli attributi sono disponibili su tutti i sistemi operativi! Su Windows non ci sono i permessi POSIX, mentre su Linux non ci sono gli attributi DOS.
- Usa sempre try-catch! I metodi possono lanciare UnsupportedOperationException o IOException.
- I permessi di accesso non sono sempre solo «rwx»! Su Windows il modello dei permessi è diverso; «sola lettura» può essere impostato dalle policy di sicurezza del sistema operativo.
- I file nascosti sono un concetto relativo. Su Unix un file è nascosto se il nome inizia con un punto (.hidden), su Windows — se è impostato l’attributo dos:hidden.
Tabella: quali attributi sono disponibili dove
| Attributo | Windows (dos:*) | Linux/macOS (posix:*) |
|---|---|---|
| Data di creazione | + | + |
| Ultima modifica | + | + |
| Ultimo accesso | + | + |
| File nascosto | + | Solo nome con punto |
| Sola lettura | + | + |
| Permessi (rwx) | - | + |
| Proprietario, gruppo | - | + |
| Archivio, di sistema | + | - |
7. Errori tipici nella gestione degli attributi dei file
Errore n° 1: tentare di leggere o modificare attributi POSIX su Windows. Su Windows otterrai UnsupportedOperationException. Gestisci sempre questa eccezione se scrivi codice cross‑platform.
Errore n° 2: modificare l’ora di modifica di un file aperto da un altro processo. In alcuni sistemi il file può essere bloccato e l’operazione terminerà con un errore.
Errore n° 3: aspettarsi che l’operazione «nascondi file» funzioni allo stesso modo su tutti i sistemi operativi. Su Unix un file è nascosto se il nome inizia con un punto (.gitignore), mentre su Windows — se è impostato l’attributo dos:hidden. Non confondere questi approcci.
Errore n° 4: trascurare la verifica dell’esistenza del file prima dell’operazione. Se il file non esiste, otterrai NoSuchFileException quando tenterai di ottenere o modificare gli attributi.
Errore n° 5: mancata verifica dei permessi di accesso. Se l’utente non ha i permessi per modificare gli attributi, l’operazione terminerà con un errore. Prima delle modifiche verifica Files.isWritable(path).
GO TO FULL VERSION