#始めに
Java nioで追加された[walkFileTree](https://docs.oracle.com/javase/jp/7/api/java/nio/file/Files.html#walkFileTree(java.nio.file.Path, java.util.Set, int, java.nio.file.FileVisitor))を使うと、ディレクトリを渡り歩く処理がめっちゃ楽だった、という記事を書いてみます
・・・・・
いや、今更というのは痛いほどわかっているんですが、職場の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を活用して無駄なファイルの入出力を抑止すること
ですかね?
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;
}
}
#感想
めっちゃ楽!の一言です
ディレクトリ処理にありがちな面倒くさいループや再帰処理が一切出てこなくなるので、ロジックがとてもシンプルになります