Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
9
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@neko_the_shadow

特定のディレクトリの下にあるファイルを再帰的に探索したい

とあるディレクトリの下にあるファイルを再帰的に探索する必要が最近ありました。Javaの標準apiにそのような機能が用意されていると思いきや、意外もないとのこと。

2016-12-29追記_: 「標準にはない」と書いていますが、実はいろいろあるとのご指摘をいただいています。詳しくはコメント欄を参照してください。

たとえば次のような構造のディレクトリがあるとします。

D:\>tree D:\temp /f
フォルダー パスの一覧:  ボリューム Data
ボリューム シリアル番号は C4C7-10BC です
D:\TEMP
│  テキスト0.txt
│
├─フォルダ1
│  │  テキスト1.txt
│  │
│  └─フォルダ1-1
│          テキスト1-1.txt
│
├─フォルダ2
│      テキスト1.txt
│
└─フォルダ3
        テキスト3.txt

このD:\tempの下にあるファイルを再帰的に探索する場合は以下のようにします。

package folder;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class FolderUtils {

    public static void main(String[] args) {

        String absolutePath = "D:\\temp";
        List<File> files = FolderUtils.findAllFile(absolutePath);
        for (File file : files) System.out.println(file.getAbsolutePath());
            // D:\temp\フォルダ2\テキスト1.txt
            // D:\temp\フォルダ1\フォルダ1-1\テキスト1-1.txt
            // D:\temp\フォルダ1\テキスト1.txt
            // D:\temp\フォルダ3\テキスト3.txt
            // D:\temp\テキスト0.txt

    }


    /**
     * 与えられたディレクトリの下にあるファイルを再帰的に探索する。
     * @param absolutePath ディレクトリの絶対パス。
     * @return ファイルの一覧
     */
    public static List<File> findAllFile(String absolutePath) {

        List<File> files = new ArrayList<>();

        Stack<File> stack = new Stack<>();
        stack.add(new File(absolutePath));
        while (!stack.isEmpty()) {
            File item = stack.pop();
            if (item.isFile()) files.add(item);

            if (item.isDirectory()) {
                for (File child : item.listFiles()) stack.push(child);
            }
        }

        return files;
    }
}

アルゴリズムは深さ優先探索。ディレクトリならその直下を探索し、それ以外ならリストに記録するだけの単純なものです。深さ優先探索と相性のいい再帰呼び出しではなく、スタックを用いた実装にしているのは効率的な実装を目指したから――ではなく、単にJavaにスタックがあることを知って使いたかったからです(´・ω・) 大した理由がなくてすみません(´・ω・)

9
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
9
Help us understand the problem. What is going on with this article?