CodeGym /Corsi /JAVA 25 SELF /Lavorare con le directory: creazione, eliminazione, visua...

Lavorare con le directory: creazione, eliminazione, visualizzazione del contenuto

JAVA 25 SELF
Livello 35 , Lezione 4
Disponibile

1. Creazione delle directory

La directory (ossia cartella) non è solo un contenitore per file, ma la base dell’organizzazione dei dati sul disco. Nelle applicazioni creiamo continuamente cartelle per dati di input/output, log, file temporanei ecc. Le API moderne di java.nio.file lo rendono comodo e multipiattaforma.

Vediamo come creare, eliminare e visualizzare il contenuto delle cartelle usando le classi Files, Path e Paths.

Files.createDirectory(path)

Crea una directory nel percorso indicato. Se la directory padre è assente — verrà lanciata un’eccezione.

import java.nio.file.*;

public class DirectoryDemo {
    public static void main(String[] args) throws Exception {
        Path dir = Paths.get("testDir");
        if (!Files.exists(dir)) {
            Files.createDirectory(dir);
            System.out.println("Directory creata: " + dir.toAbsolutePath());
        } else {
            System.out.println("La directory esiste già: " + dir.toAbsolutePath());
        }
    }
}

Se provi a creare una directory che esiste già, otterrai FileAlreadyExistsException.

Files.createDirectories(path)

Crea l’intera catena di directory. Se una delle directory intermedie manca — verrà creata automaticamente. Se parte della catena esiste già — non ci sarà alcun errore.

Path nestedDir = Paths.get("parent/child/grandchild");
Files.createDirectories(nestedDir);
System.out.println("Catena di directory creata: " + nestedDir.toAbsolutePath());

È come chiedere a Java di costruire non solo la casa, ma anche l’ingresso e la strada, se non esistono ancora.

Esempio tipico: creiamo la struttura per un progetto

Supponiamo di dover salvare i report nella cartella output/reports/2024. Non controllare ogni directory manualmente — usa createDirectories.

Path reportsPath = Paths.get("output/reports/2024");
Files.createDirectories(reportsPath);

Java capirà da sola cosa esiste già e cosa va creato.

2. Eliminazione di file e directory

Files.delete(path)

Elimina un file o una directory vuota. Se la directory non è vuota — verrà lanciata DirectoryNotEmptyException.

Path dir = Paths.get("testDir");
try {
    Files.delete(dir);
    System.out.println("Directory eliminata: " + dir.toAbsolutePath());
} catch (DirectoryNotEmptyException e) {
    System.out.println("Impossibile eliminare: la directory non è vuota!");
}

Files.deleteIfExists(path)

Funziona come delete, ma non lancia un errore se l’oggetto non esiste. Restituisce true se qualcosa è stato eliminato, e false — se l’oggetto non c’era.

Path file = Paths.get("output/reports/2024/report.txt");
if (Files.deleteIfExists(file)) {
    System.out.println("File eliminato.");
} else {
    System.out.println("File non trovato, non è stato eliminato nulla.");
}

Come eliminare una directory non vuota?

Non è possibile eliminare direttamente una cartella non vuota. Prima bisogna eliminare tutto il suo contenuto (file e sottodirectory), e poi la cartella stessa. Si fa in modo ricorsivo, ad esempio tramite Files.walkFileTree:

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class DeleteDirectoryRecursively {
    public static void main(String[] args) throws IOException {
        Path dir = Paths.get("parent");
        if (Files.exists(dir)) {
            Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file);
                    return FileVisitResult.CONTINUE;
                }
                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                }
            });
            System.out.println("La directory e tutto il suo contenuto sono stati eliminati.");
        }
    }
}

Se stai iniziando, non spaventarti di questo codice — più avanti analizzeremo walkFileTree in dettaglio.

3. Visualizzare il contenuto di una directory

Files.list(path)

Restituisce Stream<Path> — uno stream di percorsi. Puoi elaborare il contenuto della cartella tramite lo Stream API. Ogni elemento è un file o una sottodirectory (senza ricorsione!).

Path dir = Paths.get("output/reports");
if (Files.exists(dir) && Files.isDirectory(dir)) {
    try (var stream = Files.list(dir)) {
        stream.forEach(path -> System.out.println(path.getFileName()));
    }
}

Dettaglio importante: lo stream va chiuso, quindi usiamo il try‑with‑resources.

Esempio: stampiamo i nomi dei file e delle sottodirectory

Path reports2024 = Paths.get("output/reports/2024");
try (var stream = Files.list(reports2024)) {
    stream.forEach(path -> {
        String type = Files.isDirectory(path) ? "directory" : "file";
        System.out.println(path.getFileName() + " — " + type);
    });
}

Ottenere l’elenco dei file come collezione

List<Path> files = Files.list(reports2024)
    .filter(Files::isRegularFile)
    .toList();

System.out.println("File nella cartella:");
files.forEach(System.out::println);

Importante: Files.list(path) restituisce solo il contenuto della directory corrente (livello superiore). Per l’attraversamento ricorsivo usa Files.walk(path).

4. Pratica: mini file manager

L’utility crea la directory mydata/logs, il file log1.txt, stampa il contenuto della cartella e poi elimina tutto.

import java.nio.file.*;
import java.io.IOException;

public class MiniFileManager {
    public static void main(String[] args) throws IOException {
        Path logsDir = Paths.get("mydata/logs");
        Files.createDirectories(logsDir);

        Path logFile = logsDir.resolve("log1.txt");
        Files.writeString(logFile, "Ciao, log!");

        System.out.println("Contenuto della cartella " + logsDir + ":");
        try (var stream = Files.list(logsDir)) {
            stream.forEach(path -> System.out.println(" - " + path.getFileName()));
        }

        Files.deleteIfExists(logFile);
        Files.deleteIfExists(logsDir);
        System.out.println("File e cartella eliminati.");
    }
}

Commenti al codice:

  • Files.createDirectories garantisce la creazione dell’intera catena.
  • resolve — un modo comodo per aggiungere al percorso il nome di un file.
  • Chiudiamo lo stream di Files.list con try‑with‑resources — particolarmente critico su Windows.

5. Particolarità e dettagli

Verifica dell’esistenza

Prima di creare/eliminare è utile verificare se il percorso esiste:

if (!Files.exists(path)) {
    Files.createDirectory(path);
}

Permessi di accesso

Se il programma non ha i permessi per creare/eliminare — otterrai AccessDeniedException. Ad esempio, creare una cartella nella radice del disco come utente normale quasi sempre terminerà con un errore.

Directory vuota e non vuota

Si può eliminare solo una directory vuota (Files.delete). Per eliminare con tutto il contenuto usa un attraversamento ricorsivo (walkFileTree).

Multipiattaforma

L’API java.nio.file funziona correttamente su tutti i sistemi operativi più diffusi e tiene conto dei separatori di percorso. Per costruire i percorsi usa Paths.get e Path.resolve, non concatenare stringhe.

Collegamenti simbolici

Nei casi di base puoi non pensarci, ma se trovi voci «insolite» che non sono né un file normale né una directory — potrebbero essere symlink. Ci torneremo nelle lezioni avanzate.

6. Errori tipici nel lavoro con le directory

Errore n. 1: tentativo di eliminare una directory non vuota con una semplice chiamata Files.delete(path). Java lancerà DirectoryNotEmptyException. Prima elimina il contenuto, poi la cartella stessa.

Errore n. 2: dimenticare di chiudere lo stream da Files.list(). Se non usi il try‑with‑resources, lo stream rimarrà aperto e su Windows è possibile un errore durante l’eliminazione della cartella.

Errore n. 3: creazione di una directory senza controllare la presenza del genitore. La chiamata a Files.createDirectory per un percorso del tipo parent/child, quando parent non esiste, porterà a NoSuchFileException. Usa Files.createDirectories.

Errore n. 4: uso di percorsi assoluti senza necessità. Preferisci percorsi relativi all’interno del progetto — il codice sarà più portabile.

Errore n. 5: IOException non gestita. Qualsiasi operazione con il file system può terminare con un errore. Incapsula in try-catch oppure ripropaga l’eccezione verso l’alto.

Errore n. 6: tentativo di creare/eliminare in una cartella a cui non hai permessi. In questo caso otterrai AccessDeniedException. Verifica il contesto di esecuzione e i permessi di accesso.

1
Compito
JAVA 25 SELF, livello 35, lezione 4
Bloccato
Organizziamo i report: Cartelle annuali 📂
Organizziamo i report: Cartelle annuali 📂
1
Compito
JAVA 25 SELF, livello 35, lezione 4
Bloccato
Inventario nel deposito di asset di gioco 📦
Inventario nel deposito di asset di gioco 📦
1
Sondaggio/quiz
Lavorare con i file, livello 35, lezione 4
Non disponibile
Lavorare con i file
Lavorare con i file
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION