Java
nio

Java:ディレクトリを渡り歩く

More than 1 year has passed since last update.

始めに

Java nioで追加されたwalkFileTreeを使うと、ディレクトリを渡り歩く処理がめっちゃ楽だった、という記事を書いてみます
・・・・・
いや、今更というのは痛いほどわかっているんですが、職場のJREのバージョンがいまだに1.6基準なのでファイルの処理でいまだにJava.ioクラスを使っているんですよ。
walkFileTreeで実装されているVistorの処理を自前で実装したりとか、めっちゃ泣けてきます・・・・

やりたいこと

C:/Java/jdk1.8.0_102/srcからC:/Java/jdk1.8.0_102/src/javax/scriptにあるJavaファイルのpublicクラスを抽出します
publicクラスの抽出は機能の記事で挙げたソースをカスタマイズしています

walkFileTreeに渡すVistorの実装

FileVisitorインターフェイスで定義されているメソッドをオーバーライドしていきます
ポイントは

  • 戻り値でnullを返すと予期せぬところでNullPointerExceptionが発生するので、FileVisitResultを返すこと
  • preVisitDirectoryを活用して無駄なファイルの入出力を抑止すること

ですかね?

DirectroyWalkVistor.java
package triple;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;

public class DirectroyWalkVistor  implements FileVisitor<Path>{
    private static final String DIRECTORY_ON_TARGET ="C:/Java/jdk1.8.0_102/src/javax/script";

    public static void main(String args[]) throws Exception{
        Files.walkFileTree(Paths.get("C:/Java/jdk1.8.0_102/src"), new DirectroyWalkVistor());
    }

    @Override
    public FileVisitResult postVisitDirectory(Path file , IOException arg1) throws IOException {
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult preVisitDirectory(Path file, BasicFileAttributes arg1) throws IOException {
        if(Paths.get(DIRECTORY_ON_TARGET).startsWith(file)){
            //C:/Java/jdk1.8.0_102/src/javax/scriptに部分一致するときは処理を続ける
            return FileVisitResult.CONTINUE;
        }else{
            //C:/Java/jdk1.8.0_102/src/javax/scriptに部分一致しない時はサブディレクトリの処理をスキップする
            return FileVisitResult.SKIP_SUBTREE;
        }
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes arg1) throws IOException {
        try{
            JavaFileAnalyser.execute(file);
        }catch(Exception e){
            throw new IOException(e);
        }
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException arg1) throws IOException {
        arg1.printStackTrace();
        return FileVisitResult.CONTINUE;
    }
}

感想

めっちゃ楽!の一言です
ディレクトリ処理にありがちな面倒くさいループや再帰処理が一切出てこなくなるので、ロジックがとてもシンプルになります