山下寛人オフィシャルブログ

オイシックス株式会社 執行役員 システム本部長 山下寛人の公式ブログです。

Javaでファイル検索(Files.walkFileTree)

今日Javaでファイル検索するプログラムを

作りました。

便利なAPIが増えていて簡単にできました。

java.nioパッケージのFilesクラスです。

サブディレクトリをたどっていく検索や

コピーが簡単にできます。

プログラムはこんな具合です。

Path path = Paths.get("検索するディレクトリのパス");
// anonymous class can only access "final" variable
// and final variable can't rewrite
final List maxdate = new ArrayList();
maxdate.add(0);
final List target = new ArrayList();
target.add(null);
Files.walkFileTree(path, EnumSet.noneOf(FileVisitOption.class), 3,
new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
String fileName = file.getFileName().toString();
if (fileName.matches(".*アクション.*店舗.*")) {
String dateStr = fileName.substring(0, 6);
if (dateStr.matches("^[0-9]+$")) {
int date = Integer.parseInt(dateStr);
if (date > maxdate.get(0)) {
maxdate.set(0, date);
target.set(0, file);
}
}
}
return FileVisitResult.CONTINUE;
}
});
Files.copy(target.get(0),
Paths.get("コピー先のパス"),
StandardCopyOption.REPLACE_EXISTING);

説明します。

メインはFiles.walkFileTree()です。

引数はパス、オプション、たどるサブディレクトリ階層の

数、FileVisitorオブジェクトです。

オプションと階層の数は省略できます。

FileVisitorオブジェクトはコールバックに

なっていて、1ファイルごとにそれぞれの

メソッドが呼び出されます。

インターフェースは4つメソッドがありますが

簡易的なものの場合はSimpleFileVisitorの

無名クラスにすればよいでしょう。

visitFileメソッドにコールバックメソッド

実装します。

ここでは正規表現にマッチしたファイルを

対象に、先頭6文字を取り出して一番数が

大きいものを1個抽出するようにしています。


ここで、maxdateやtargetが1つしかないのに

わざわざArrayListにしています。

これは、無名クラスからだと外側のローカル

変数にアクセスできないためです。

例外的にfinalにしているとアクセスできます。

しかしfinalだと値が書き換えられません。

なのでオブジェクトにしてその中身を

操作しています。

まあ、変則的な書き方ですが。

こういう、なんでこんなことしてんの?

というコードにはコメントを書きましょう。


Pathオブジェクトのインスタンスを作るときは

Paths.get()メソッドが便利です。


Java8だとこういう無名クラスを使うパターンは

ラムダ式でもっと簡潔に書けるみたいですね。

そちらは未検証なので省略します。