別に目新しくもなんともないのですが、なんとなく投稿してみます。
掲題のような処理を行うには、Java7で追加されてたFiles#walkFileTree()がよさそうです。
WalkFileTreeSample.java
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.io.*;
public class WalkFileTreeSample {
public static void main(String[] args) throws IOException {
Path start = Paths.get("/Users/daiki/go");
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
});
}
}
SimpleFileVisitorは普通のクラスであり、関数型インタフェースじゃないのでラムダ式は使えません。
上記ではファイルごとに呼び出されるメソッドのみをオーバーライドしてますが、他にもディレクトリを訪問する前に呼び出されるメソッド、後に呼び出されるメソッドなどがあり、オーバーライドすることで処理を挟むことができます。
別の例として、Java8で追加されてたFiles#walk()を使うこともできます。こちらはStream APIを使います。上のと結果を合わせるため、ディレクトリは除外しています。ちょっと気持ち悪い?
WalkSample.java
import java.io.IOException;
import java.nio.file.*;
import java.util.stream.Stream;
public class WalkSample {
public static void main(String[] args) throws IOException {
Path start = Paths.get("/path/to/target");
try(Stream<Path> paths = Files.walk(start)) {
paths.filter(path -> !Files.isDirectory(path))
.forEach(System.out::println);
}
}
}
Java6以前であれば、再帰を使って自分で書くことになりますかね。ただファイル名を出力するだけなら、特に難しいことはありませんが。
WalkWithoutLibrarySample.java
import java.io.File;
public class WalkWithoutLibrarySample {
public static void main(String[] args) {
File start = new File("/path/to/target");
walk(start);
}
private static void walk(File dir) {
for(File file : dir.listFiles()) {
if(file.isFile()) {
System.out.println(file);
} else {
walk(file);
}
}
}
}