Documentation

The Java™ Tutorials
Hide TOC
Creating and Reading Directories创建和读取目录
Trail: Essential Java Classes
Lesson: Basic I/O
Section: File I/O (Featuring NIO.2)

Creating and Reading Directories创建和读取目录

Some of the methods previously discussed, such as delete, work on files, links and directories. 前面讨论的一些方法,例如删除、处理文件、链接和目录。But how do you list all the directories at the top of a file system? 但是如何列出文件系统顶部的所有目录?How do you list the contents of a directory or create a directory?如何列出目录的内容或创建目录?

This section covers the following functionality specific to directories:本节介绍特定于目录的以下功能:

Listing a File System's Root Directories列出文件系统的根目录

You can list all the root directories for a file system by using the FileSystem.getRootDirectories method. 您可以通过使用FileSystem.getRootDirectories方法列出文件系统的所有根目录。This method returns an Iterable, which enables you to use the enhanced for statement to iterate over all the root directories.此方法返回一个Iterable,使您能够使用增强的for语句迭代所有根目录。

The following code snippet prints the root directories for the default file system:以下代码段打印默认文件系统的根目录:

Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();
for (Path name: dirs) {
    System.err.println(name);
}

Creating a Directory创建目录

You can create a new directory by using the createDirectory(Path, FileAttribute<?>) method. 您可以使用createDirectory(Path, FileAttribute<?>)方法创建新目录。If you don't specify any FileAttributes, the new directory will have default attributes. 如果未指定任何FileAttributes,则新目录将具有默认属性。For example:例如:

Path dir = ...;
Files.createDirectory(path);

The following code snippet creates a new directory on a POSIX file system that has specific permissions:以下代码段在具有特定权限的POSIX文件系统上创建新目录:

Set<PosixFilePermission> perms =
    PosixFilePermissions.fromString("rwxr-x---");
FileAttribute<Set<PosixFilePermission>> attr =
    PosixFilePermissions.asFileAttribute(perms);
Files.createDirectory(file, attr);

To create a directory several levels deep when one or more of the parent directories might not yet exist, you can use the convenience method, createDirectories(Path, FileAttribute<?>). 要在一个或多个父目录可能不存在时创建多个层次的目录,可以使用方便的方法createDirectories(Path, FileAttribute<?>)As with the createDirectory(Path, FileAttribute<?>) method, you can specify an optional set of initial file attributes. createDirectory(Path, FileAttribute<?>)方法一样,您可以指定一组可选的初始文件属性。The following code snippet uses default attributes:以下代码段使用默认属性:

Files.createDirectories(Paths.get("foo/bar/test"));

The directories are created, as needed, from the top down. 根据需要,从上到下创建目录。In the foo/bar/test example, if the foo directory does not exist, it is created. foo/bar/test示例中,如果foo目录不存在,则创建它。Next, the bar directory is created, if needed, and, finally, the test directory is created.接下来,如果需要,创建bar目录,最后创建测试目录。

It is possible for this method to fail after creating some, but not all, of the parent directories.在创建一些(但不是全部)父目录后,此方法可能会失败。

Creating a Temporary Directory创建临时目录

You can create a temporary directory using one of createTempDirectory methods:您可以使用createTempDirectory方法之一创建临时目录:

The first method allows the code to specify a location for the temporary directory and the second method creates a new directory in the default temporary-file directory.第一种方法允许代码指定临时目录的位置,第二种方法在默认的临时文件目录中创建一个新目录。

Listing a Directory's Contents列出目录的内容

You can list all the contents of a directory by using the newDirectoryStream(Path) method. 您可以使用newDirectoryStream(Path)方法列出目录的所有内容。This method returns an object that implements the DirectoryStream interface. 此方法返回实现DirectoryStream接口的对象。The class that implements the DirectoryStream interface also implements Iterable, so you can iterate through the directory stream, reading all of the objects. 实现DirectoryStream接口的类也实现了Iterable,因此您可以遍历目录流,读取所有对象。This approach scales well to very large directories.这种方法可以很好地扩展到非常大的目录。


Remember:谨记: The returned DirectoryStream is a stream. 返回的DirectoryStream是一个If you are not using a try-with-resources statement, don't forget to close the stream in the finally block. 如果您没有使用try-with-resources语句,请不要忘记在finally块中关闭流。The try-with-resources statement takes care of this for you. try-with-resources语句为您解决了这一问题。

The following code snippet shows how to print the contents of a directory:以下代码段显示了如何打印目录的内容:

Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
    for (Path file: stream) {
        System.out.println(file.getFileName());
    }
} catch (IOException | DirectoryIteratorException x) {
    // IOException can never be thrown by the iteration.
    // In this snippet, it can only be thrown by newDirectoryStream.
    System.err.println(x);
}

The Path objects returned by the iterator are the names of the entries resolved against the directory. 迭代器返回的Path对象是根据目录解析的条目的名称。So, if you are listing the contents of the /tmp directory, the entries are returned with the form /tmp/a, /tmp/b, and so on.因此,如果您列出了/tmp目录的内容,则返回的条目格式为/tmp/a/tmp/b等等。

This method returns the entire contents of a directory: files, links, subdirectories, and hidden files. 此方法返回目录的全部内容:文件、链接、子目录和隐藏文件。If you want to be more selective about the contents that are retrieved, you can use one of the other newDirectoryStream methods, as described later in this page.如果希望对检索的内容更具选择性,可以使用其他newDirectoryStream方法之一,如本页后面所述。

Note that if there is an exception during directory iteration then DirectoryIteratorException is thrown with the IOException as the cause. 请注意,如果目录迭代期间出现异常,则会引发DirectoryIteratorException,并将IOException作为原因。Iterator methods cannot throw exception exceptions.迭代器方法无法引发异常。

Filtering a Directory Listing By Using Globbing使用Globbing筛选目录列表

If you want to fetch only files and subdirectories where each name matches a particular pattern, you can do so by using the newDirectoryStream(Path, String) method, which provides a built-in glob filter. 如果只想获取每个名称与特定模式匹配的文件和子目录,可以使用newDirectoryStream(Path, String)方法来实现,该方法提供了内置的glob过滤器。If you are not familiar with glob syntax, see What Is a Glob?如果您不熟悉glob语法,请参阅什么是glob?

For example, the following code snippet lists files relating to Java: .class, .java, and .jar files.:例如,以下代码段列出了与Java相关的文件:.class.java.jar文件:

Path dir = ...;
try (DirectoryStream<Path> stream =
     Files.newDirectoryStream(dir, "*.{java,class,jar}")) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    // IOException can never be thrown by the iteration.
    // In this snippet, it can // only be thrown by newDirectoryStream.
    System.err.println(x);
}

Writing Your Own Directory Filter编写自己的目录筛选器

Perhaps you want to filter the contents of a directory based on some condition other than pattern matching. 也许您希望根据模式匹配以外的某些条件筛选目录的内容。You can create your own filter by implementing the DirectoryStream.Filter<T> interface. 您可以通过实现DirectoryStream.Filter<T>接口来创建自己的筛选器。This interface consists of one method, accept, which determines whether a file fulfills the search requirement.此接口由一个方法accept组成,该方法确定文件是否满足搜索要求。

For example, the following code snippet implements a filter that retrieves only directories:例如,以下代码段实现了仅检索目录的筛选器:

DirectoryStream.Filter<Path> filter =
    newDirectoryStream.Filter<Path>() {
    public boolean accept(Path file) throws IOException {
        try {
            return (Files.isDirectory(path));
        } catch (IOException x) {
            // Failed to determine if it's a directory.
            System.err.println(x);
            return false;
        }
    }
};

Once the filter has been created, it can be invoked by using the newDirectoryStream(Path, DirectoryStream.Filter<? super Path>) method. 创建筛选器后,可以使用newDirectoryStream(Path, DirectoryStream.Filter<? super Path>)方法调用它。The following code snippet uses the isDirectory filter to print only the directory's subdirectories to standard output:以下代码段使用isDirectory筛选器仅将目录的子目录打印到标准输出:

Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
    for (Path entry: stream) {
        System.out.println(entry.getFileName());
    }
} catch (IOException x) {
    System.err.println(x);
}

This method is used to filter a single directory only. 此方法仅用于筛选单个目录。However, if you want to find all the subdirectories in a file tree, you would use the mechanism for Walking the File Tree.但是,如果要查找文件树中的所有子目录,可以使用遍历文件树的机制。


Previous page: Random Access Files
Next page: Links, Symbolic or Otherwise