web-dev-qa-db-ja.com

FileUtils.listFilesを使用してディレクトリのみを再帰的に検索する

特にサブディレクトリを含む、ディレクトリの下のallファイルのリストを収集したいと思います。私は自分で物事をするのが好きではないので、Apache CommonsIOのFileUtils.listFilesを使用しています。だから私は次のようなものを持っています:

import Java.io.File;
import Java.util.Collection;

import org.Apache.commons.io.FileUtils;
import org.Apache.commons.io.filefilter.TrueFileFilter;

public class TestListFiles {
  public static void main(String[] args) {
    Collection<File> found = FileUtils.listFiles(new File("foo"),
        TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
    for (File f : found) {
      System.out.println("Found file: " + f);
    }
  }
}

問題は、これは通常のファイルのみを検索し、ディレクトリは検索しないように見えることです。

$ mkdir -p foo/bar/baz; touch foo/one_file
$ Java -classpath commons-io-1.4.jar:. TestListFiles
Found file: foo/one_file

私はすでに両方のフィルターにTrueFileFilterを渡しているので、これ以上包括的なものは考えられません。リストしたい:"foo", "foo/one_file", "foo/bar", "foo/bar/baz"(任意の順序)。

FileUtils以外のソリューションも受け入れますが、独自のBFSを作成する必要がある、または取得したリストから親ディレクトリのセットを収集する必要があるのはばかげているようです。 (とにかく空のサブディレクトリを見逃してしまいます。)これはLinux、FWIWにあります。

18
Dave B

古い答えですが、これは私にとってはうまくいきます:

FileUtils.listFilesAndDirs(new File(dir), TrueFileFilter.INSTANCE, DirectoryFileFilter.DIRECTORY);

両方を示しています:

私が使う:

FileUtils.listFilesAndDirs(new File(dir), new NotFileFilter(TrueFileFilter.INSTANCE), DirectoryFileFilter.DIRECTORY)

ディレクトリのみを表示し、ファイルは表示しません...

20
DOS

ソースコード を見て、JavaDocの行間を読むと、残念ながら、このAPIは目的の動作をするように設計されていないことがわかります。 ファイルのリストを返します(ファイルとディレクトリのリストではありません)提供された引数に一致します。ソースコードで-メソッドinnerListFilesを見てください-ディレクトリが検索され、notが結果リストに追加されていないことがわかります。

私はあなたが望むことをするパブリックAPIを知りません。うまくいけば、他の誰かがそれを知っているでしょう。ほとんどはおそらくBFSではなくDFSであり、目的に関係する場合と関係しない場合があります。 (これまでのところ、allJavaこれまでに見たコードは、ディレクトリツリートラバーサルが深さ優先探索を介して実行しました。もちろん、BFSが存在しないという意味ではありません。)

特定のディレクトリの下にあるすべてのリストが本当に必要な場合は、自分で作成するのは簡単です。しかし、私はあなたが車輪の再発明をしたくないというあなたの願いを理解しています。

注: Apache Commons Finder が必要なものをサポートする可能性がありますが、このライブラリはThe Commons Sandboxにあるため、この段階ではより実験的です。完全な場合とそうでない場合があり、維持される場合とされない場合があります。それはまたあなたが探しているものにとって重いかもしれません。

6
Eddie

簡単に試しましたか:

File rootFolder = new File(...);
File[] folders = rootFolder.listFiles((FileFilter) FileFilterUtils.directoryFileFilter());

それは私のために働くようです。もちろん、再帰が必要になります。

それが役に立てば幸い。

6
user573041

私は、ほとんどの重要なアプリケーションでJava IOライブラリを使用せず、代わりにCommons VFSを優先します。 このメソッド 適切なパラメータを使用すれば目標は達成されますが、機能を実現するには長い道のりがあります。

具体的には、このコードはあなたが望むことをします:

    FileObject[] files = fileObject.findFiles(new FileSelector() {
        public boolean includeFile(FileSelectInfo fileInfo)  {
            return fileInfo.getFile().getType() == FileType.FOLDER; }

        public boolean traverseDescendents(FileSelectInfo fileInfo) {
            return true;
        }
    });

ここで、fileObjectはFileObjectのインスタンスです。

6
Jherico

より簡単で完全な Commons VFS ソリューション:

FileSystemManager fsManager = VFS.getManager();
FileObject fileObject = fsManager.resolveFile( "yourFileNameHere" );
FileObject[] files = fileObject.findFiles( new FileTypeSelector( FileType.FOLDER ) )
1
javamonkey79

APIに基づいて機能するはずです。

これが私自身のバージョンの FileUtils であり、Commons IOほど完全ではなく、必要なものだけが含まれています。 findFilesを検索するか、iterateを使用して巨大なリストの作成を回避できます(いつか/ほとんどの場合、それらのファイルで何かをしたいので、リストにそれらを収集することは意味がありません)。

0
adrian.tarau