Categories: Java

【Java入門】ディレクトリ内のファイルを再帰的に取得する方法

JavaSE6以前の書き方

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以降の書き方

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がオススメ!同僚に差をつけよう!

issiki_wp