315

Javaのディレクトリの下にあるすべてのファイルを再帰的に一覧表示するにはどうすればよいですか? フレームワークはユーティリティを提供しますか?

ハックな実装をたくさん見ました。しかし、フレームワークやnioからはありません

4

30 に答える 30

411

Java 8 provides a nice stream to process all files in a tree.

Files.walk(Paths.get(path))
        .filter(Files::isRegularFile)
        .forEach(System.out::println);

This provides a natural way to traverse files. Since it's a stream you can do all nice stream operations on the result such as limit, grouping, mapping, exit early etc.

UPDATE: I might point out there is also Files.find which takes a BiPredicate that could be more efficient if you need to check file attributes.

Files.find(Paths.get(path),
           Integer.MAX_VALUE,
           (filePath, fileAttr) -> fileAttr.isRegularFile())
        .forEach(System.out::println);

Note that while the JavaDoc eludes that this method could be more efficient than Files.walk it is effectively identical, the difference in performance can be observed if you are also retrieving file attributes within your filter. In the end, if you need to filter on attributes use Files.find, otherwise use Files.walk, mostly because there are overloads and it's more convenient.

TESTS: As requested I've provided a performance comparison of many of the answers. Check out the Github project which contains results and a test case.

于 2014-06-03T03:37:29.063 に答える
166

FileUtilsにはメソッドがiterateFilesありlistFilesます。それらを試してみてください。( commons-ioから)

編集:ここでさまざまなアプローチのベンチマークを確認できます。commons-io のアプローチは遅いと思われるので、ここから高速なものをいくつか選択してください(問題がある場合) 。

于 2010-01-13T11:36:05.433 に答える
142

// 実行準備完了

import java.io.File;

public class Filewalker {

    public void walk( String path ) {

        File root = new File( path );
        File[] list = root.listFiles();

        if (list == null) return;

        for ( File f : list ) {
            if ( f.isDirectory() ) {
                walk( f.getAbsolutePath() );
                System.out.println( "Dir:" + f.getAbsoluteFile() );
            }
            else {
                System.out.println( "File:" + f.getAbsoluteFile() );
            }
        }
    }

    public static void main(String[] args) {
        Filewalker fw = new Filewalker();
        fw.walk("c:\\" );
    }

}
于 2010-01-13T11:47:57.890 に答える
71

Java 7Files.walkFileTreeがあります。

開始点とファイル ビジターを指定すると、ファイル ツリー内のファイルをウォークスルーするときに、ファイル ビジターでさまざまなメソッドが呼び出されます。再帰的なコピー、再帰的な移動、再帰的な削除、またはパーミッションを設定するか、各ファイルに対して別の操作を実行する再帰的な操作を開発している場合は、これを使用することを期待しています。

現在、この質問に関する完全な Oracle チュートリアルがあります。

于 2010-01-13T11:52:49.667 に答える
29

外部ライブラリは必要ありません。
Collection を返すので、呼び出し後に必要なことを行うことができます。

public static Collection<File> listFileTree(File dir) {
    Set<File> fileTree = new HashSet<File>();
    if(dir==null||dir.listFiles()==null){
        return fileTree;
    }
    for (File entry : dir.listFiles()) {
        if (entry.isFile()) fileTree.add(entry);
        else fileTree.addAll(listFileTree(entry));
    }
    return fileTree;
}
于 2012-07-25T20:36:19.450 に答える
19

私は次のようなものに行きます:

public void list(File file) {
    System.out.println(file.getName());
    File[] children = file.listFiles();
    for (File child : children) {
        list(child);
    }
}

System.out.println は、ファイルに対して何かを行うことを示すためのものです。通常のファイルには子がないだけなので、ファイルとディレクトリを区別する必要はありません。

于 2010-01-13T11:39:33.073 に答える
15

この種の単純なトラバージョンには、再帰よりもキューを使用することを好みます。

List<File> allFiles = new ArrayList<File>();
Queue<File> dirs = new LinkedList<File>();
dirs.add(new File("/start/dir/"));
while (!dirs.isEmpty()) {
  for (File f : dirs.poll().listFiles()) {
    if (f.isDirectory()) {
      dirs.add(f);
    } else if (f.isFile()) {
      allFiles.add(f);
    }
  }
}
于 2012-05-30T10:17:21.180 に答える
12

単純な再帰を使用して自分で書くだけです:

public List<File> addFiles(List<File> files, File dir)
{
    if (files == null)
        files = new LinkedList<File>();

    if (!dir.isDirectory())
    {
        files.add(dir);
        return files;
    }

    for (File file : dir.listFiles())
        addFiles(files, file);
    return files;
}
于 2010-01-13T11:36:26.480 に答える
7

Java 8 では、Files ユーティリティを使用してファイル ツリーをたどることができるようになりました。とてもシンプルです。

Files.walk(root.toPath())
      .filter(path -> !Files.isDirectory(path))
      .forEach(path -> System.out.println(path));
于 2014-10-05T12:38:38.600 に答える
7

私はこれが仕事をするべきだと思います:

File dir = new File(dirname);
String[] files = dir.list();

このようにして、ファイルとディレクトリがあります。ここで、再帰を使用して、dirs ( Fileclass has isDirectory()method ) に対して同じことを行います。

于 2010-01-13T11:35:53.687 に答える
4

再帰的なトラバーサルとは別に、ビジター ベースのアプローチも使用できます。

以下のコードは、トラバーサルに訪問者ベースのアプローチを使用しています。プログラムへの入力は、トラバースするルート ディレクトリであることが期待されます。

public interface Visitor {
    void visit(DirElement d);
    void visit(FileElement f);
}

public abstract class Element {
    protected File rootPath;
    abstract void accept(Visitor v);

    @Override
    public String toString() {
        return rootPath.getAbsolutePath();
    }
}

public class FileElement extends Element {
    FileElement(final String path) {
        rootPath = new File(path);
    }

    @Override
    void accept(final Visitor v) {
        v.visit(this);
    }
}

public class DirElement extends Element implements Iterable<Element> {
    private final List<Element> elemList;
    DirElement(final String path) {
        elemList = new ArrayList<Element>();
        rootPath = new File(path);
        for (File f : rootPath.listFiles()) {
            if (f.isDirectory()) {
                elemList.add(new DirElement(f.getAbsolutePath()));
            } else if (f.isFile()) {
                elemList.add(new FileElement(f.getAbsolutePath()));
            }
        }
    }

    @Override
    void accept(final Visitor v) {
        v.visit(this);
    }

    public Iterator<Element> iterator() {
        return elemList.iterator();
    }
}

public class ElementWalker {
    private final String rootDir;
    ElementWalker(final String dir) {
        rootDir = dir;
    }

    private void traverse() {
        Element d = new DirElement(rootDir);
        d.accept(new Walker());
    }

    public static void main(final String[] args) {
        ElementWalker t = new ElementWalker("C:\\temp");
        t.traverse();
    }

    private class Walker implements Visitor {
        public void visit(final DirElement d) {
            System.out.println(d);
            for(Element e:d) {
                e.accept(this);
            }
        }

        public void visit(final FileElement f) {
            System.out.println(f);
        }
    }
}
于 2010-01-13T12:53:58.933 に答える
3

以下のコードを使用して、特定のフォルダーまたはディレクトリのファイルのリストを再帰的に取得できます。

public static void main(String args[]) {

        recusiveList("D:");

    }

    public static void recursiveList(String path) {

        File f = new File(path);
        File[] fl = f.listFiles();
        for (int i = 0; i < fl.length; i++) {
            if (fl[i].isDirectory() && !fl[i].isHidden()) {
                System.out.println(fl[i].getAbsolutePath());
                recusiveList(fl[i].getAbsolutePath());
            } else {
                System.out.println(fl[i].getName());
            }
        }
    }
于 2017-06-23T05:25:44.040 に答える
2

すべてのファイル/ファイル名を再帰的に出力するためにこれを思いつきました。

private static void printAllFiles(String filePath,File folder) {
    if(filePath==null) {
        return;
    }
    File[] files = folder.listFiles();
    for(File element : files) {
        if(element.isDirectory()) {
            printAllFiles(filePath,element);
        } else {
            System.out.println(" FileName "+ element.getName());
        }
    }
}
于 2019-08-02T17:40:30.067 に答える
-1

スタッカーの回答に基づいています。これは、外部ライブラリなしで JSP で動作するソリューションであるため、サーバーのほぼどこにでも配置できます。

<!DOCTYPE html>
<%@ page session="false" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html; charset=UTF-8" %>

<%!
    public List<String> files = new ArrayList<String>();
    /**
        Fills files array with all sub-files.
    */
    public void walk( File root ) {
        File[] list = root.listFiles();

        if (list == null) return;

        for ( File f : list ) {
            if ( f.isDirectory() ) {
                walk( f );
            }
            else {
                files.add(f.getAbsolutePath());
            }
        }
    }
%>
<%
    files.clear();
    File jsp = new File(request.getRealPath(request.getServletPath()));
    File dir = jsp.getParentFile();
    walk(dir);
    String prefixPath = dir.getAbsolutePath() + "/";
%>

次に、次のようなことを行います。

    <ul>
        <% for (String file : files) { %>
            <% if (file.matches(".+\\.(apk|ipa|mobileprovision)")) { %>
                <li><%=file.replace(prefixPath, "")%></li>
            <% } %>
        <% } %>
    </ul>
于 2014-01-21T09:32:36.970 に答える