---
title: Fileの再帰的検索
tags: [File, JProgressBar, SwingWorker]
author: aterai
pubdate: 2003-12-15
description: 指定したDirectory以下のFileを再帰的に検索し、その進捗状況をJProgressBarで表示します。
---
* 概要 [#la10adfb]
指定した`Directory`以下の`File`を再帰的に検索し、その進捗状況を`JProgressBar`で表示します。

#download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTRh7du1II/AAAAAAAAAhU/jcMUoOTcbTU/s800/RecursiveFileSearch.png)

* サンプルコード [#n78bba98]
#code(link){{
private void recursiveSearch(File dir, final List<File> list)
        throws InterruptedException {
  for (String fname : dir.list()) {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
    File sdir = new File(dir, fname);
    if (sdir.isDirectory()) {
      recursiveSearch(sdir, list);
    } else {
      scount++;
      if (scount % 100 == 0) {
        publish(new Message("Results:" + scount + "\n", false));
      }
      list.add(sdir);
    }
  }
}
}}

* 解説 [#l9b71aa9]
上記のサンプルでは、選択したフォルダ以下のファイルを再帰的にすべて検索して表示するようになっています。

----
`JProgressBar`を使った進捗状況の表示とキャンセルには、`SwingWorker`を利用しています。

----
`JDK 1.7.0`以上の場合は、`Files.walkFileTree(...)`などを使用する方法もあります。

- [http://docs.oracle.com/javase/jp/7/api/java/nio/file/Files.html#walkFileTree(java.nio.file.Path,%20java.nio.file.FileVisitor) Files#walkFileTree(...) (Java Platform SE 7)]
- [http://docs.oracle.com/javase/tutorial/essential/io/walk.html Walking the File Tree (The Java™ Tutorials > Essential Classes > Basic I/O)]

#code{{
private void recursiveSearch(Path dir, final ArrayList<Path> list) throws IOException {
  Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
    @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      if (Thread.interrupted()) {
        throw new IOException();
      }
      if (attrs.isRegularFile()) {
        list.add(file);
      }
      return FileVisitResult.CONTINUE;
    }
  });
}
}}

----
`JDK 1.8.0`以上の場合は、`Files.walk(Path)`を使用する方法もあります。

- [http://docs.oracle.com/javase/jp/8/api/docs/java/nio/file/Files.html#walk-java.nio.file.Path-java.nio.file.FileVisitOption...- Files#walk(Path) (Java Platform SE 8)]
- [http://www.ne.jp/asahi/hishidama/home/tech/java/files.html#walk Javaファイル関連メモ2(Hishidama's Java Files Memo)]
- [http://stackoverflow.com/questions/1844688/read-all-files-in-a-folder java - Read all files in a folder - Stack Overflow]

#code{{
import java.util.*;
import java.util.stream.*;
import java.io.IOException;
import java.nio.file.*;
public class FilesWalkTest {
  public static void main(String[] args) {
    Path dir = Paths.get(".");
    //Files.walk(dir).forEach(System.out::println);
    try (Stream<Path> s = Files.walk(dir)
                               .filter(Files::isRegularFile)) {
      List<Path> l = s.collect(Collectors.toList());
      System.out.println(l.size());
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }
}
}}

* 参考リンク [#oc687cdf]
- [http://msugai.fc2web.com/java/IO/fileObj.html Java入門 ファイル]
- [http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html How to Use Progress Bars]
- [http://docs.oracle.com/javase/jp/6/api/javax/swing/SwingWorker.html SwingWorker (Java Platform SE 6)]
- [http://web.archive.org/web/20090830092511/http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html Using a Swing Worker Thread]

* コメント [#v7736a30]
#comment
- 実際に動作するサンプルを追加してみました。 -- &user(aterai); &new{2006-04-28 (金) 21:50:55};
- `JDK 6`の`SwingWorker`を使用するように変更しました。 -- &user(aterai); &new{2008-07-11 (金) 15:32:26};

#comment