Автор оригинала: Mona Mohamadinia.
1. Обзор
В этом кратком руководстве мы познакомимся с различными способами проверки существования файла или каталога.
Во-первых, мы начнем с современных API NIO, а затем рассмотрим устаревшие подходы ввода-вывода.
2. Использование java.nio.file.Файлы
Чтобы проверить, существует ли файл или каталог, мы можем использовать метод Files.exists(Path) . Как видно из сигнатуры метода, сначала мы должны получить путь к предполагаемому файлу или каталогу. Затем мы можем передать этот Путь | в Files.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(Путь) или Files.isRegularFile(Путь) методы:
assertTrue(Files.isDirectory(tempDirectory)); assertFalse(Files.isDirectory(tempFile)); assertTrue(Files.isRegularFile(tempFile));
Существует также метод notExists(Path) , который возвращает true если данный Путь не существует:
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 .
Можно даже не следовать по символическим ссылкам, передавая соответствующий Опция Ссылки в качестве второго аргумента:
assertTrue(Files.exists(symbolicLink, LinkOption.NOFOLLOW_LINKS));
Поскольку сама ссылка существует, метод Files.exists(Path) возвращает true. Кроме того, мы можем проверить, является ли Path символической ссылкой, используя метод Files.isSymbolicLink(Path) |:
assertTrue(Files.isSymbolicLink(symbolicLink)); assertFalse(Files.isSymbolicLink(target));
3. Использование java.io.File
Если мы используем Java 7 или более новую версию Java, настоятельно рекомендуется использовать современные API Java NIO для таких требований .
Однако, чтобы убедиться, что файл или каталог существует в Java legacy IO world, мы можем вызвать метод exists () | на экземплярах File |:
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());
Как показано выше, метод exists () не заботится о том, является ли он файлом или каталогом. Поэтому, пока он существует, он будет возвращать 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 и устаревших API ввода-вывода. Кроме того, мы видели, как NIO API обрабатывает символические ссылки.
Как обычно, все примеры доступны на GitHub .