# Java 列出目录内容

原文：http://zetcode.com/articles/javalistdirectory/

Java 列表目录教程显示了如何以 Java 显示目录内容。

## 目录定义

目录是计算机文件系统中用于存储和定位文件的组织单位。 目录按层次结构组织成目录树。 目录具有亲子关系。

## Java 列出目录的类

我们可以使用以下 Java 类列出目录内容：

*   `java.nio.file.Files`
*   `org.apache.commons.io.FileUtils`
*   `java.io.File`

## 使用`Files.list`非递归列出目录内容

`Files.list()`方法返回`Path`对象的延迟填充流。 该列表不是递归的。

`JavaFilesList.java`

```java
package com.zetcode;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

public class JavaFilesList {

    public static void main(String[] args) throws IOException {

        String dirName = "/home/janbodnar/prog/";

        Files.list(new File(dirName).toPath())
                .limit(10)
                .forEach(path -> {
                    System.out.println(path);
                });
    }
}

```

本示例显示给定目录中的十个文件或目录。

## 使用`Files.walk`递归列出目录内容

`Files.walk()`方法通过遍历以给定起始文件为根的文件树来返回`Paths`的延迟填充流。 `Files.walk()`递归遍历所有子目录。

`JavaFilesWalk.java`

```java
package com.zetcode;

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

public class JavaFilesWalkFilter {

    public static void main(String[] args) throws IOException {
        try (Stream<Path> paths = Files.walk(Paths.get("/home/janbodnar/prog"))) {
            paths.filter(Files::isRegularFile)
                    .forEach(System.out::println);
        }
    }
}

```

本示例使用`Files.walk()`方法显示给定目录的内容。 使用`filter()`方法，我们将目录的内容过滤为仅包含常规文件。

## 用 Apache Commons IO 列出目录内容

Apache commons 的`FileUtils.listFiles()`允许递归和非递归列出目录内容。

```java
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

```

对于这个例子，我们需要这种依赖项。

`JavaDirectoryContentsApacheCommons.java`

```java
package com.zetcode;

import java.io.File;
import java.util.List;
import org.apache.commons.io.FileUtils;

public class JavaDirectoryContentsApacheCommons {

    public static void main(String[] args) {

        String dirName = "/home/janbodnar/tmp/";

        List<File> files = (List<File>) FileUtils.listFiles(new File(dirName), null, true);

        files.forEach(System.out::println);
    }
}

```

该代码示例使用`FileUtils.listFiles()`递归显示目录内容。

```java
List<File> files = (List<File>) FileUtils.listFiles(new File(dirName), null, true);

```

`FileUtils.listFiles()`的第一个参数是要列出的目录名称。 第二个参数是应与列表匹配的扩展名数组。 如果给出`null`，则返回所有文件。 第三个参数确定列表是否是递归的； 即，也搜索所有子目录。

## 使用`Files.walkFileTree`非递归列出目录内容

`Files.walkFileTree()`方法遍历以给定起始文件为根的文件树。 它使用`FileVisitor`模式来指定遍历过程中关键点的必需行为：访问文件时，访问目录之前，访问目录之后或发生故障时。

`JavaWalkFilesTree.java`

```java
package com.zetcode;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;

public class JavaWalkFilesTree {

    public static void main(String[] args) throws IOException {

        String dirName = "/home/janbodnar/prog";
        File file = new File(dirName);

        Files.walkFileTree(file.toPath(), Collections.emptySet(), 1, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println(file);
                return FileVisitResult.CONTINUE;
            }
        });        
    }
}

```

该示例使用`Files.walkFileTree()`非递归地遍历目录。

```java
Files.walkFileTree(file.toPath(), Collections.emptySet(), 1, new SimpleFileVisitor<Path>() {

```

`Files.walkFileTree()`参数是：起始文件，配置遍历的选项，要访问的最大目录级别数，为每个文件调用的文件访问者。 在我们的情况下，我们需要遍历一个目录级别。

## 使用`Files.walkFileTree`递归列出目录内容

在下面的示例中，我们使用`Files.walkFileTree()`遍历整个目录结构。

`JavaWalkFilesTree.java`

```java
package com.zetcode;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class JavaWalkFilesTree {

    public static void main(String[] args) throws IOException {
        String dirName = "/home/janbodnar/prog";
        File file = new File(dirName);

        Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println(file);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

```

该示例使用重载的`Files.walkFileTree()`方法来递归遍历目录。

## 使用`File`非递归列出目录内容

`java.io.File`类是一个较旧的 API，用于列出目录内容。 它没有前面提到的现代 API 强大。 `File`的`listFiles()`返回给定目录中的文件对象数组。

`JavaDirectoryContentsFile.java`

```java
package com.zetcode;

import java.io.File;

public class JavaDirectoryContentsFile {

    public static void main(String[] args) {

        String dirName = "/home/janbodnar/tmp/";

        File fileName = new File(dirName);
        File[] fileList = fileName.listFiles();

        for (File file: fileList) {

            System.out.println(file);
        }
    }
}

```

该示例将给定目录的内容打印到控制台。 它不会进入子目录。

## 用`File`递归列出目录内容

这次我们使用`java.io.File`类递归列出目录。

`JavaDirectoryContentsFileRecursive.java`

```java
package com.zetcode;

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

public class JavaDirectoryContentsFileRecursive {

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

    public static void main(String[] args) {

        String dirName = "/home/janbodnar/tmp/";

        File file = new File(dirName);

        List<File> myfiles = doListing(file);

        myfiles.forEach(System.out::println);
    }

    public static List<File> doListing(File dirName) {

        File[] fileList = dirName.listFiles();

        for (File file : fileList) {

            if (file.isFile()) {

                files.add(file);
            } else if (file.isDirectory()) {

                files.add(file);
                doListing(file);
            }
        }

        return files;
    }
}

```

`doListing()`方法列出目录的内容。 我们使用`isDirectory()`方法确定文件是否为目录，然后在每个子目录上递归调用`doListing()`。

在本教程中，我们展示了使用 Java 列出目录内容的各种方法。

您可能也对以下相关教程感兴趣：[以 Java 读取文本文件](/articles/javareadtext/)， [Java 附加到文件](/articles/javaappendtofile/)，[以 Java 复制文件](/java/copyfile/)， [Java 教程](/lang/java/) ，[用 Java8 的`StringJoiner`连接字符串](/articles/java8stringjoiner/) ，[Java 读取页面](/articles/javareadwebpage/)或 [Google Guava 简介](/articles/guava/)。