Check If a File or Directory Exists in Java – 检查一个文件或目录是否存在于Java中

最后修改: 2020年 8月 2日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’re going to get familiar with different ways to check the existence of a file or directory.

在这个快速教程中,我们将熟悉检查一个文件或目录是否存在的不同方法。

First, we’ll start with the modern NIO APIs and then will cover the legacy IO approaches.

首先,我们将从现代的NIO API开始,然后将介绍传统的IO方法。

2. Using java.nio.file.Files

2.使用java.nio.file.Files

To check if a file or directory exists, we can leverage the Files.exists(Path) method. As it’s clear from the method signature, we should first obtain a Path to the intended file or directory. Then we can pass that Path to the Files.exists(Path) method:

为了检查一个文件或目录是否存在,我们可以利用Files.exists(Path)方法。从方法的签名中可以看出,我们首先应该获得一个Path到预定的文件或目录。然后我们可以将该Path传递给Files.exists(Path) 方法。

Path path = Paths.get("does-not-exist.txt");
assertFalse(Files.exists(path));

Since the file doesn’t exist, it returns false. It’s also worth mentioning that if the Files.exists(Path) method encounters an IOException, it’ll return false, too.

由于该文件不存在,它返回false。值得一提的是,如果Files.exists(Path)方法遇到IOException,它也会返回false

On the other hand, when the given file exists, it’ll return true as expected:

另一方面,当给定的文件存在时,它将按预期返回true

Path tempFile = Files.createTempFile("baeldung", "exist-article");
assertTrue(Files.exists(tempFile));

Here we’re creating a temporary file and then calling the Files.exists(Path) method.

这里我们创建一个临时文件,然后调用Files.exists(Path) 方法。

This even works for directories:

这甚至适用于目录

Path tempDirectory = Files.createTempDirectory("baeldung-exists");
assertTrue(Files.exists(tempDirectory));

If we specifically want to know if a file or directory exists, we can also use Files.isDirectory(Path) or Files.isRegularFile(Path) methods:

如果我们特别想知道一个文件或目录是否存在,我们也可以使用Files.isDirectory(Path) 或者 Files.isRegularFile(Path) 方法:

assertTrue(Files.isDirectory(tempDirectory));
assertFalse(Files.isDirectory(tempFile));
assertTrue(Files.isRegularFile(tempFile));

There is also a notExists(Path) method that returns true if the given Path doesn’t exist:

还有一个notExists(Path)方法,如果给定的Path不存在,则返回true

assertFalse(Files.notExists(tempDirectory));

Sometimes the Files.exists(Path) returns false because we don’t possess the required file permissions. In such scenarios, we can use the Files.isReadable(Path) method to make sure the file is actually readable by the current user:

有时,Files.exists(Path)会返回false,因为我们不具备所需的文件权限。在这种情况下,我们可以使用Files.isReadable(Path) 方法来确保文件确实可被当前用户读取。

assertTrue(Files.isReadable(tempFile));
assertFalse(Files.isReadable(Paths.get("/root/.bashrc")));

2.1. Symbolic Links

2.1 符号链接

By default, the Files.exists(Path) method follows the symbolic links. If file has a symbolic link to file B, then the Files.exists(A) method returns true if and only if the file exists already:

默认情况下,Files.exists(Path)方法遵循符号链接。如果文件A 有一个指向文件B的符号链接,那么Files.exists(A)方法返回true ,如果且仅当文件B已经存在。

Path target = Files.createTempFile("baeldung", "target");
Path symbol = Paths.get("test-link-" + ThreadLocalRandom.current().nextInt());
Path symbolicLink = Files.createSymbolicLink(symbol, target);
assertTrue(Files.exists(symbolicLink));

Now if we delete the target of the link, the Files.exists(Path) will return false:

现在,如果我们删除链接的目标,Files.exists(Path) 将返回false

Files.deleteIfExists(target);
assertFalse(Files.exists(symbolicLink));

Since the link target doesn’t exist anymore, following the link won’t lead to anything, and Files.exists(Path) will return false.

由于链接的目标不再存在,跟随链接将不会有任何结果,Files.exists(Path)将返回false

It’s even possible to not follow the symbolic links by passing an appropriate LinkOption as the second argument:

甚至可以通过传递适当的LinkOption作为第二个参数来不遵循符号链接:

assertTrue(Files.exists(symbolicLink, LinkOption.NOFOLLOW_LINKS));

Because the link itself exists, the Files.exists(Path) method returns true. Also, we can check if a Path is a symbolic link using the Files.isSymbolicLink(Path) method:

因为链接本身存在,Files.exists(Path)方法返回true。此外,我们可以使用Path 是一个符号链接,a href=”https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Files.html#isSymbolicLink(java.nio.file.Path)”>Files.isSymbolicLink(Path) 方法来检查。

assertTrue(Files.isSymbolicLink(symbolicLink));
assertFalse(Files.isSymbolicLink(target));

3. Using java.io.File

3.使用java.io.File

If we’re using Java 7 or a newer version of Java, it’s highly recommended to use the modern Java NIO APIs for these sorts of requirements.

如果我们使用Java 7或更新的Java版本,强烈建议使用现代的Java NIO API来满足这类要求

However, to make sure if a file or directory exists in Java legacy IO world, we can call the exists() method on File instances:

然而,为了确保文件或目录在Java传统IO世界中是否存在,我们可以在exists() 方法上调用File 实例。

assertFalse(new File("invalid").exists());

If the file or directory does exist already, it’ll return true:

如果该文件或目录确实已经存在,它将返回true

Path tempFilePath = Files.createTempFile("baeldung", "exist-io");
Path tempDirectoryPath = Files.createTempDirectory("baeldung-exists-io");

File tempFile = new File(tempFilePath.toString());
File tempDirectory = new File(tempDirectoryPath.toString());

assertTrue(tempFile.exists());
assertTrue(tempDirectory.exists());

As shown above, the exists() method doesn’t care if it’s a file or directory. Therefore, as long as it does exist, it’ll return true

如上所示,exists()方法并不关心它是一个文件还是目录。因此,只要它确实存在,它就会返回true

The isFile() method, however, returns true if the given path is an existing file:

然而,isFile() 方法,如果给定的路径是一个现有文件,则返回true

assertTrue(tempFile.isFile());
assertFalse(tempDirectory.isFile());

Similarly, the isDirectory() method returns true if the given path is an existing directory:

同样,isDirectory()方法如果给定的路径是一个现有的目录,则返回true

assertTrue(tempDirectory.isDirectory());
assertFalse(tempFile.isDirectory());

Finally, the canRead() method returns true if the file is readable:

最后,canRead()方法返回true如果文件是可读的。

assertTrue(tempFile.canRead());
assertFalse(new File("/root/.bashrc").canRead());

When it returns false, the file either doesn’t exist or the current user doesn’t possess the read permission on the file.

当它返回false时,该文件要么不存在,要么当前用户不拥有该文件的读取权限。

4. Conclusion

4.总结

In this short tutorial, we saw how to make sure a file or directory exists in Java. Along the way, we talked about modern NIO and the legacy IO APIs. Also, we saw how the NIO API handles symbolic links.

在这个简短的教程中,我们看到了如何确保一个文件或目录在Java中存在。在此过程中,我们谈到了现代NIO和传统的IO APIs。此外,我们还看到了NIO API如何处理符号链接。

As usual, all the examples are available over on GitHub.

像往常一样,所有的例子都可以在GitHub上找到