Java、ファイルではなく、ディレクトリのサブディレクトリのみをリスト


100

Javaでは、ディレクトリからサブディレクトリのみを一覧表示するにはどうすればよいですか?

java.io.File機能を使用したいのですが、Javaでこれを行うのに最適な方法は何ですか。

回答:


141

Fileクラスを使用して、ディレクトリを一覧表示できます。

File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
  @Override
  public boolean accept(File current, String name) {
    return new File(current, name).isDirectory();
  }
});
System.out.println(Arrays.toString(directories));

更新

この投稿に対する著者からのコメントは、より速い方法、ここでの素晴らしい議論を望んでいました:Javaでディレクトリのリストをすばやく 取得する方法は?

基本的に:

  1. あなたがファイル構造を制御するなら、私はそのような状況に入るのを避けようとします。
  2. Java NIO.2では、ディレクトリ関数を使用してイテレータを返し、より大きなスケーリングを可能にすることができます。ディレクトリストリームクラスは、ディレクトリ内のエントリを反復処理するために使用できるオブジェクトです。

こんにちは、返信ありがとうございます。しかし、ディレクトリ内のすべてのアイテムを反復処理する必要はありません。ディレクトリからサブディレクトリを直接リストする必要があります。B'cozたくさんのファイルがあり、ディレクトリにはサブディレクトリが少ないので、isDirectory()のチェックには時間がかかります。別の方法で返信してください。
Lokesh Paunikar、2011

私は私の投稿を更新しました。特に、質問に対するJon Skeetコメントを見てください。また、Java NIO 2には、ディレクトリのストリームを返すディレクトリ関数のイテレータがあるため、NIO応答が返されます。
Mohamed Mansour

どのスキートコメントを参照していますか?ここでより良い答えは何ですか?
Stealth Rabbi

107

非常にシンプルなJava 8ソリューション:

File[] directories = new File("/your/path/").listFiles(File::isDirectory);

FileFilterを使用するのと同じです(古いJavaでも動作します)。

File[] directories = new File("/your/path/").listFiles(new FileFilter() {
    @Override
    public boolean accept(File file) {
        return file.isDirectory();
    }
});

4
::この場合、二重コロンはどのように機能しますか?
snickers10m 2015

FileFilterを使用する他の回答がないことに気づいたので、メソッド参照を使用せずに同等のバージョンを追加しました。メソッドリファレンスの詳細については、このSOの質問またはこの記事を参照してください
headsvk

これは/ your / path /の直下のサブディレクトリまたはディレクトリだけを取得しますか?
アマダイン


14

@Mohamed Mansourあなたはほとんどそこにいました...あなたが使用していたことからの「dir」引数は実際には現在のパスなので、常にtrueを返します。子がサブディレクトリかどうかを確認するには、その子をテストする必要があります。

File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
  @Override
  public boolean accept(File current, String name) {
    return new File(current, name).isDirectory();
  }
});
System.out.println(Arrays.toString(directories));

7

Java 7とNIO.2を使用するソリューションに興味がある場合は、次のようになります。

private static class DirectoriesFilter implements Filter<Path> {
    @Override
    public boolean accept(Path entry) throws IOException {
        return Files.isDirectory(entry);
    }
}

try (DirectoryStream<Path> ds = Files.newDirectoryStream(FileSystems.getDefault().getPath(root), new DirectoriesFilter())) {
        for (Path p : ds) {
            System.out.println(p.getFileName());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

3
ArrayList<File> directories = new ArrayList<File>(
    Arrays.asList(
        new File("your/path/").listFiles(File::isDirectory)
    )
);

こんにちは、StackOverflowへようこそ!答えを少し詳しく説明していただけますか?コードスニペットの興味深い部分を説明したり、さらに読むためにドキュメントにリンクしたりしますか?
Richard-Degenne

Fileオブジェクトに完全な正規パスを提供するため、これは正しい答えになるはずです。これは古いかもしれませんが、指摘する価値があります
Jero Dungog

2

Java 7とNIOにも興味がある場合は、上記の@vooの回答に対する代替ソリューションがあります。呼び出し行うtry-with-resourcesFiles.find()、ディレクトリのフィルタリングに使用されるラムダ関数を使用できます。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;


final Path directory = Paths.get("/path/to/folder");

try (Stream<Path> paths = Files.find(directory, Integer.MAX_VALUE, (path, attributes) -> attributes.isDirectory())) {
    paths.forEach(System.out::println);
} catch (IOException e) {
    ...
}

lambda関数を変更して、名前でディレクトリをフィルタリングすることもできます。

(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")

または日付順:

final long now = System.currentTimeMillis();
final long yesterday = new Date(now - 24 * 60 * 60 * 1000L).getTime();

// modified in the last 24 hours
(path, attributes) -> attributes.isDirectory() && attributes.lastModifiedTime().toMillis() > yesterday

2

java.io.File機能を使用したいのですが、

2012年(質問の日付)はい、今日ではありません。 java.nioAPIは、このような要件に対応する必要があります。

非常に多くの回答がありますが、私がそれを使用する単純な方法ではありませんFiles.walk().filter().collect()

グローバルに2つのアプローチが可能です。

1)制限Files.walk(Path start, )はありませんmaxDepth

2)Files.walk(Path start, int maxDepth, FileVisitOption... options)それを設定することができます。

深さの制限を指定しないと、次のようになります。

Path directory = Paths.get("/foo/bar");

try {
    List<Path> directories =
            Files.walk(directory)
                 .filter(Files::isDirectory)
                 .collect(Collectors.toList());
} catch (IOException e) {
    // process exception
}

そして、レガシーな理由で、あなたがリストを取得する必要があるなら、Fileあなたは単にmap(Path::toFile)収集の前に操作を追加することができます:

Path directory = Paths.get("/foo/bar");

try {
    List<File> directories =
            Files.walk(directory)
                 .filter(Files::isDirectory)
                 .map(Path::toFile)
                 .collect(Collectors.toList());
} catch (IOException e) {
    // process exception
}

Files.list(Path)おそらくと同じものもありFiles.walk(Path,1)ます。
David L.

@David L Indeed Files.list(Path)は、フォルダーを再帰的に繰り返したくない場合の公正な代替手段です。フォルダを再帰的に繰り返すには、walk()より適しています。
davidxxx

1

私のために働いた解決策は、答えのリストから欠落しています。したがって、私はこのソリューションをここに投稿しています:

File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());

ここではorg.apache.commons.io.filefilter.FileFilterUtils、Apache commons-io-2.2.jarから使用しています。ドキュメントはこちらから入手できます:https : //commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html


0

開始ディレクトリが String

  1. Stringパスをパラメーターとして取るメソッドを作成します。メソッド内:
  2. 開始ディレクトリに基づいて新しいFileオブジェクトを作成します
  3. listFilesメソッドを使用して、現在のディレクトリにあるファイルの配列を取得します
  4. ファイルの配列をループする
    1. ファイルの場合は、ループを続けます
    2. ディレクトリの場合は、名前を出力し、この新しいディレクトリパスで再帰します。

こんにちは、返信ありがとうございます。しかし、ディレクトリ内のすべてのアイテムを反復処理する必要はありません。ディレクトリからサブディレクトリを直接リストする必要があります。B'cozたくさんのファイルがあり、ディレクトリにはサブディレクトリが少ないので、isDirectory()のチェックには時間がかかります。別の方法で返信してください。
Lokesh Paunikar、2011

0

これが私のコードの解決策です。私は最初の答えから少し変更しました。これにより、目的のディレクトリにあるすべてのフォルダが1行ずつ表示されます。

try {
            File file = new File("D:\\admir\\MyBookLibrary");
            String[] directories = file.list(new FilenameFilter() {
              @Override
              public boolean accept(File current, String name) {
                return new File(current, name).isDirectory();
              }
            });
            for(int i = 0;i < directories.length;i++) {
                if(directories[i] != null) {
                    System.out.println(Arrays.asList(directories[i]));

                }
            }
        }catch(Exception e) {
            System.err.println("Error!");
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.