Files.walk în Java

Parcurge un folder cu tot ce conține, la orice adâncime, și dă toate căile ca Stream<Path>, începând cu folderul însuși.

Sintaxă
static Stream<Path> walk(Path start, FileVisitOption... optiuni) throws IOException
static Stream<Path> walk(Path start, int adancimeMaxima, FileVisitOption... optiuni) throws IOException

Ce face Files.walk

Files.walk(start) pornește din folderul dat și intră în toate subfolderele. Stream-ul conține folderul de start, apoi fiecare fișier și subfolder găsit. Fiecare folder apare înaintea conținutului său.

Cu al doilea argument limitezi adâncimea: walk(start, 1) este ca Files.list, plus folderul de start. Ordinea fraților în același folder nu este garantată, deci sortează la afișare. Ca la list, folosește try-with-resources.

Parametri

Parametru Descriere
start Folderul de unde pornește parcurgerea.
adancimeMaxima Opțional: câte niveluri sub start să parcurgă.
optiuni Opțional: FileVisitOption.FOLLOW_LINKS.

Ce returnează

Un Stream<Path> cu toate căile găsite (trebuie închis).

Exemple

Exemplul 1: Tot arborele unui proiect

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) throws IOException {
        Path site = Path.of("site");
        Files.createDirectories(site.resolve("css"));
        Files.createDirectories(site.resolve("pagini/blog"));
        Files.writeString(site.resolve("index.html"), "<h1>Salut</h1>");
        Files.writeString(site.resolve("css/stil.css"), "body {}");
        Files.writeString(site.resolve("pagini/blog/java.html"), "<p>Java</p>");

        try (Stream<Path> toate = Files.walk(site)) {
            toate.sorted().forEach(p -> System.out.println((Files.isDirectory(p) ? "[D] " : "    ") + p));
        }
    }
}

Rezultat

[D] site
[D] site/css
    site/css/stil.css
    site/index.html
[D] site/pagini
[D] site/pagini/blog
    site/pagini/blog/java.html

Exemplul 2: Toate fișierele .html, căutate în adâncime

Al doilea apel limitează adâncimea la 1, deci nu mai găsește pagina din pagini/blog.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) throws IOException {
        Path site = Path.of("site");
        Files.createDirectories(site.resolve("pagini/blog"));
        Files.writeString(site.resolve("index.html"), "");
        Files.writeString(site.resolve("pagini/contact.html"), "");
        Files.writeString(site.resolve("pagini/blog/java.html"), "");

        try (Stream<Path> s = Files.walk(site)) {
            System.out.println(s.filter(p -> p.toString().endsWith(".html")).sorted().toList());
        }
        try (Stream<Path> s = Files.walk(site, 1)) {
            System.out.println(s.filter(p -> p.toString().endsWith(".html")).sorted().toList());
        }
    }
}

Rezultat

[site/index.html, site/pagini/blog/java.html, site/pagini/contact.html]
[site/index.html]

Greșeli frecvente

  • Pornești walk din rădăcina discului sau din folderul utilizatorului: parcurgerea poate dura foarte mult și poate da AccessDeniedException pe foldere protejate.
  • Ștergi elementele în ordinea dată de walk: folderele vin înaintea conținutului și ștergerea lor eșuează. Sortează invers (Comparator.reverseOrder()).

Comenzi înrudite

  • Files.list: Returnează conținutul direct al unui folder (fișiere și subfoldere, fără să intre în ele), ca Stream<Path>.
  • Files.delete: Șterge un fișier sau un folder gol; delete aruncă excepție dacă lipsește, deleteIfExists doar returnează false.
  • Files.isDirectory: isDirectory spune dacă la cale este un folder, iar isRegularFile dacă este un fișier obișnuit.
  • Stream.filter: Păstrează în stream doar elementele care îndeplinesc o condiție.