1. 概要

このクイックチュートリアルでは、ファイルまたはディレクトリの存在を確認するさまざまな方法を理解します。

まず、最新のNIO APIから始めて、次にレガシーIOアプローチについて説明します。

2. java.nio.file.Filesを使用する

ファイルまたはディレクトリが存在するかどうかを確認するには、Files.exists(Path)メソッドを利用できます。 メソッドシグネチャから明らかなように、最初に目的のファイルまたはディレクトリへのパスを取得する必要があります。 次に、その PathFiles.exists(Path)メソッドに渡すことができます。

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

ファイルが存在しないため、falseを返します。 Files.exists(Path)メソッドで IOException が発生した場合も、falseが返されることにも言及しておく価値があります。

一方、指定されたファイルが存在する場合、期待どおりにtrueが返されます。

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

ここでは、一時ファイルを作成してから、 Files.exists(Path)メソッドを呼び出しています。

これはディレクトリでも機能します

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

ファイルまたはディレクトリが存在するかどうかを具体的に知りたい場合は、 Files.isDirectory(Path)または Files.isRegularFile(Path)メソッドを使用することもできます。

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

指定されたパスが存在しない場合にtrueを返すnotExists(Path)メソッドもあります。

assertFalse(Files.notExists(tempDirectory));

必要なファイル権限がないためにFiles.exists(Path)がfalseを返すことがあります。 このようなシナリオでは、 Files.isReadable(Path)メソッドを使用して、ファイルが現在のユーザーによって実際に読み取り可能であることを確認できます。

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

2.1. シンボリックリンク

デフォルトでは、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));

ここで、リンクのターゲットを削除すると、 Files.exists(Path)falseを返します。

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

リンクターゲットはもう存在しないため、リンクをたどっても何も発生せず、 Files.exists(Path)falseを返します。

2番目の引数として適切なLinkOptionを渡すことにより、シンボリックリンクをたどらないことも可能です。

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

リンク自体が存在するため、 Files.exists(Path) メソッドは戻ります真実。 また、を使用したシンボリックリンクです Files.isSymbolicLink(Path) 方法:

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

3. java.io.Fileを使用する

Java 7以降のバージョンのJavaを使用している場合は、この種の要件に最新のJavaNIOAPIを使用することを強くお勧めします

ただし、ファイルまたはディレクトリがJavaレガシーIOの世界に存在するかどうかを確認するために、 Fileインスタンスでexists()メソッドを呼び出すことができます。

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

ファイルまたはディレクトリがすでに存在する場合は、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());

上に示したように、 presents()メソッドは、それがファイルであるかディレクトリであるかを気にしません。 したがって、それが存在する限り、trueを返します。 

ただし、 isFile()メソッドは、指定されたパスが既存のファイルである場合、trueを返します。

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

同様に、 isDirectory()メソッドは、指定されたパスが既存のディレクトリである場合、trueを返します。

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

最後に、 canRead()メソッドは、ファイルが読み取り可能である場合、trueを返します。

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

false が返される場合、ファイルが存在しないか、現在のユーザーがファイルの読み取り権限を持っていません。

4. 結論

この短いチュートリアルでは、ファイルまたはディレクトリがJavaに存在することを確認する方法を説明しました。 その過程で、最新のNIOとレガシーIOAPIについて話しました。 また、NIOAPIがシンボリックリンクを処理する方法も確認しました。

いつものように、すべての例はGitHubから入手できます。