【Java入門】ディレクトリ内のファイルを再帰的に取得する方法
JavaSE6以前では、ファイルを再帰的に取得するには、以下のようなコーディングをする必要がありました。
Java
    public static void main(String args[]){
        File f = new File("C:\\workspace\\sample");
        print(f);
    }
    //再帰的に取得する処理
    public static void print(File file){
        System.out.println(file.getPath());
        File[] fileList = file.listFiles();
        if(fileList != null){
            for(File f: fileList){
                   print(f);
            }
        }
    }
実行結果
C:\workspace\sample
C:\workspace\sample\dir2A
C:\workspace\sample\dir2A\dir3
C:\workspace\sample\dir2A\dir3\textA.txt
C:\workspace\sample\dir2A\textA.txt
C:\workspace\sample\dir2A\textB.txt
C:\workspace\sample\dir2B
C:\workspace\sample\dir2B\textA.txt
C:\workspace\sample\dir2B\textB.txt
C:\workspace\sample\textA.txt
JavaSE7以降では、Files#walkを使用することで、以下のように簡潔にコーディングできるようになりました。
walkメソッドは、深さ優先でファイルツリーを再帰的(トラバース)に辿り、結果をStream
Java
public static void main(String args[]){
    try(Stream<Path> stream = Files.walk(Paths.get("C:\\workspace\\sample"))){
        stream.forEach(System.out::println);
    }catch(IOException e) {
        e.printStackTrace();
    }
}
実行結果はJavaSE6のときと同じ結果になります。
実行結果
C:\workspace\sample
C:\workspace\sample\dir2A
C:\workspace\sample\dir2A\dir3
C:\workspace\sample\dir2A\dir3\textA.txt
C:\workspace\sample\dir2A\textA.txt
C:\workspace\sample\dir2A\textB.txt
C:\workspace\sample\dir2B
C:\workspace\sample\dir2B\textA.txt
C:\workspace\sample\dir2B\textB.txt
C:\workspace\sample\textA.txt
上記の例ではフォルダも一緒に取得されてしまいます。
通常ファイルのパスのみ取得したい場合は次のように記述します。
Java
//取得したパスが通常ファイルならTrueを返す。
Predicate<? super Path> isRegularFile= p -> {
    BasicFileAttributes bfa = null;
    try {
        bfa = Files.readAttributes(p, BasicFileAttributes.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
   return bfa.isRegularFile();
};
//再帰処理して通常ファイルのみパスを出力する。
Files.walk(Paths.get("C:\\workspace\\sample"))
.filter(isRegularFile)
.forEach(System.out::println);
実行結果
C:\workspace\sample\dir2A\dir3\textA.txt
C:\workspace\sample\dir2A\textA.txt
C:\workspace\sample\dir2A\textB.txt
C:\workspace\sample\dir2B\textA.txt
C:\workspace\sample\dir2B\textB.txt
C:\workspace\sample\textA.txt
以下のようにPredicateをもっと簡単に書く方法もあります。
Java
Predicate<? super Path> isRegularFile= p -> {
    //通常ファイルならTrue
    return Files.isRegularFile(p);
};
Files.walk(Paths.get("C:\\workspace\\sample"))
.filter(isRegularFile)
.forEach(System.out::println);
ディレクトリのパスのみ取得したい場合は次のようにします。
Java
//取得したパスがディレクトリならTrueを返す。
Predicate<? super Path> isDirctory = p -> {
    BasicFileAttributes bfa = null;
    try {
        bfa = Files.readAttributes(p, BasicFileAttributes.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
   return bfa.isDirectory();
};
//再帰処理してディレクトリのみパスを出力する。
Files.walk(Paths.get("C:\\workspace\\sample"))
.filter(isDirctory)
.forEach(System.out::println);
実行結果
C:\workspace\sample
C:\workspace\sample\dir2A
C:\workspace\sample\dir2A\dir3
C:\workspace\sample\dir2B
以下のようにPredicateをもっと簡単に書く方法もあります。
Java
Predicate<? super Path> isDirectory= p -> {
    //ディレクトリならTrue
    return Files.isDirectory(p);
};
Files.walk(Paths.get("C:\\workspace\\sample"))
.filter(isDirectory)
.forEach(System.out::println);
以上で記事の解説はお終い!
もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!