Javaでディレクトリ内のファイルを再帰的に処理する

こんにちは、さるまりんです。

ディレクトリ内の全てのファイルに対して処理を行うプログラムをJavaで書いてみました。
ディレクトリ内にはさらにディレクトリがありファイルがあり、それらを全て処理します。

こんな抽象クラスを作りました。
再帰的に(Recursive)ファイル(File)を処理するもの(Processor)です。

RecursiveFileProcessor.java

import java.io.File;

public abstract class RecursiveFileProcessor {

    /**
     * ディレクトリ内のファイルを処理する
     * @param dir ディレクトリ
     */
    public void processDirectory(File dir) {
        // ディレクトリのファイルを取得する
        File[] files = dir.listFiles();

        if (files == null) {
            // ファイルがないので処理終了
            return;
        }

        // ファイルを一つずつ処理する
        for (File f : files) {
            if (f.isDirectory()) {
                // 現在のファイルが「ディレクトリ」であればそのディレクトリをさらに処理
                processDirectory(f); // 自分自身を呼び出し
            } else if (f.isFile()) {
                // 現在のファイルが「ファイル」であれば、ファイルに対して実行した処理を行う
                processFile(f);
            }
        }
    }

    /**
     * 抽象メソッド:実際ファイルに対して行いたい処理はこのメソッドを
     * @param file ファイル
     */
    public abstract void processFile(File file);
}

コメントに書いてありますが、処理の流れはこんな感じです。

  1. ディレクトリ内のファイルの一覧を取得する
  2. 一覧が取得できなければ処理を終了
  3. 一覧にあるファイルを一つずつ処理
    1. ファイルが「ディレクトリ」ならこの処理を現在のディレクトリで呼び出す
    2. ファイルが「ファイル」なら、実際にしたい処理を行う

クラス自体は抽象クラスとし、3-bはprocessFile(File file)の抽象メソッドとしています。

ディレクトリ内のファイルの名前とサイズを全て表示するプログラムを作ってみました。

PrintAllFileNamesAndSizes.java

public class PrintAllFileNamesAndSizes extends RecursiveFileProcessor {

    /**
     * ファイルの名前とサイズを出力する。
     */
    public void processFile(File file) {
        System.out.println(file.getName() + " " + file.length() + " bytes");
    }

}

クラスPrintAllFileNamesAndSizesRecursiveFileProcessorを継承し、メソッドprocessFile()でファイル名とサイズを出力する処理を実装しています。

呼び出してみます。
次のコードでディレクトリ/home/salumarineにあるファイルの名前とサイズを全て出力します。

public static void main(String[] args) {
    new PrintAllFileNamesAndSizes().processDirectory(new File("/home/salumarine"));
}

再帰的に自分自身を呼び出す方法ってうまく使うと便利です。
処理を止める条件(上のプログラムではファイルの一覧が取得できなくなる状態)を考え出せればいろんなところで使えそうです。頭の体操しているみたいでちょっと楽しいです。

読んでくださってありがとうございました。

それではまた!