Рубрики
Без рубрики

Java: Проверьте, существует ли файл или каталог

Проверка наличия файла или каталога-простая и важная операция во многих задачах. В этой статье мы рассмотрим множество различных способов, которые вы можете использовать, чтобы проверить, существует ли файл или каталог, если это символическая ссылка, и недостатки этих подходов.

Автор оригинала: David Landup.

Вступление

Проверка наличия файла или каталога-простая и важная операция во многих задачах. Перед доступом к файлу мы должны проверить, существует ли он, чтобы избежать исключения NullPointerException . То же самое касается каталогов.

Хотя некоторые функции могут создавать новый файл/каталог, если запрошенный не существует, это может быть противоположностью тому, что мы хотим. Если мы хотим добавить дополнительную информацию в существующий файл, а метод выполняется без предупреждения, так как он создает необходимый ему новый файл, мы, возможно, потеряли некоторую информацию, не осознавая этого.

Здесь у нас простая структура:

02/13/2020  11:53 AM              directory
02/13/2020  11:55 AM         directory_link [directory]
02/13/2020  11:53 AM                 0 file.txt
02/13/2020  11:55 AM          symlink.txt [file.txt]

Там есть file.txt файл и symlink.txt файл. В symlink.txt файл представляет собой символическую ссылку на file.txt .

Аналогично, у нас есть каталог и символическая ссылка на него – directory_link .

Проверьте, существует ли файл

Для работы с классом Files вам необходимо ознакомиться с классом Path . Файлы принимает только Путь , а не Файл объекты.

Для целей этого урока мы определим Файл и Путь экземпляр для file.txt в нашем каталоге:

final static String location = "C:\\file.txt";

Path path = Paths.get(location);
File file = new File(location);

Файлы.существует()

Тем не менее, первый способ, которым мы можем проверить, существует ли файл, – это класс Files :

// Check if file exists through a Path
System.out.println(Files.exists(path));

// Check if a file exists by converting File object to Path
System.out.println(Files.exists(file.toPath()));

Запуск этого кода даст нам:

true
true

Файлы.Не существует()

Возможно, вам будет интересно, почему метод не существует() вообще существует:

Если существует() возвращает истину , это означает, что не существует() должно возвращать ложь . Они логически дополняют друг друга и A = !B , верно?

Ну, вот тут-то многие и ошибаются. Если Files.exists() возвращает false , это не должно означать, что файл не существует.

Это также может означать, что существование файла не может быть проверено . В этом случае оба Files.exists() и Files.notExists() вернут false , поскольку Java не может определить, существует файл или нет.

Обычно это происходит, если у вас есть файл, заблокированный таким образом, что Java не может получить к нему доступ. Представьте, что у нас есть файл, который заблокирован в нашем каталоге – lockedFile.txt :

И если бы мы попытались проверить его существование с помощью:

System.out.println(Files.exists(path));
System.out.println(Files.notExists(path));

Нас встретили бы с:

false
false

Очевидно, что он существует, но Java не имеет разрешения на подтверждение этого в нашей системе, что приводит к противоречивым результатам.

Файлы.isRegularFile()

Кроме того, мы можем проверить, является ли файл обычным файлом ( false если это каталог) с помощью метода isRegularFile() :

System.out.println(Files.isRegularFile(path));

На выходе получается:

true

Файл.isFile()

Вместо использования класса Files мы также можем выполнять методы для самих файловых объектов:

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

Это возвращает:

true

Файл.существует()

Аналогично предыдущему варианту, мы можем запустить метод exists() :

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

И это также возвращает:

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

true

Разница между этими двумя заключается в том, что первый проверяет, является ли это файлом, а другой проверяет, существует ли он. В разных обстоятельствах они дали бы разные результаты.

Заблокированные Файлы

Забавно отметить, что если вы используете Файл для проверки существования, Java может определить, существует ли заблокированный ранее файл или нет:

System.out.println(file.isFile());
System.out.println(file.exists());

Запуск этого фрагмента кода приведет к:

true
true

При этом очевидно, что заблокированный файл может быть прочитан с помощью класса File вместо вспомогательного класса Files .

Проверьте, существует ли Каталог

Каталоги-это, по сути, файлы, которые могут содержать другие файлы. Вот почему проверка того, является ли каталог файлом, вернет true . Хотя, если вы проверяете, является ли каталог каталогом (файл особого типа), вы получите более точный результат.

На этот раз мы меняем наше местоположение на:

final static String location = "C:\\directory";

Файлы.существует()

Опять же, как и в первом примере, мы можем проверить, существует ли он с помощью:

System.out.println(Files.exists(path));

На выходе получается:

true

Files.isDirectory()

Если бы мы хотели проверить, является ли это конкретным каталогом, мы бы использовали:

System.out.println(Files.isDirectory(path));

И результат таков:

true

Примечание: Если каталог не существует , метод isDirectory() вернет false . Это связано с тем, как называется метод. Что он делает – он проверяет, существует ли файл и , если это каталог, а не только последний. Файл не может быть каталогом, если он не существует – следовательно, возвращается false .

Проверьте, является ли Файл символической ссылкой

Возможно, вы также захотите проверить, является ли файл просто символической ссылкой. В этом случае вы бы использовали класс Files .

Давайте переключим наше местоположение на:

final static String location = "C:\\symlink.txt";

Файлы.isSymbolicLink()

Как обычно, класс Files принимает Путь к файлу:

System.out.println(Files.isSymbolicLink(path));

Запуск этого приведет к:

true

Файл.getCanonicalPath() против файла.getAbsolutePath()

Другой способ проверить наличие символической ссылки-сравнить результаты канонического пути к файлу и абсолютного пути. Если они разные, то, скорее всего, это символическая ссылка:

System.out.println(file.getCanonicalPath());
System.out.println(file.getAbsolutePath());

Поскольку мы проверяем наличие символической ссылки, и мы знаем, что это так, они должны возвращать другой результат – a symlink.txt и file.txt путь:

C:\symlink.txt
C:\symlink.txt

Однако здесь это не так. Это связано с тем, что символическая ссылка была создана в Windows с использованием NTFS (Файловая система новой технологии). Символическая ссылка была создана с помощью команды mklink в CMD.

Проверьте, Существует Ли Какой-Либо Из Них

Из предыдущих примеров очевидно, что метод Files.exists() вернет true как для существующих файлов, так и для каталогов. Хотя, это не работает лучше всего, когда дело доходит до заблокированных файлов.

С другой стороны, метод exists() из класса File также вернет true как для файлов, так и для каталогов и сможет прочитать заблокированный файл, который класс Files не может.

Вывод

Проверка наличия файлов и каталогов-это первая линия защиты от пропавших файлов и каталогов. Разные подходы имеют разные недостатки, и вы можете предположить, что метод вернет точный результат, но это не произойдет из-за того, как он работает в фоновом режиме.

Знание того, какие методы возвращают какие результаты и при каких обстоятельствах, позволит вам избежать неприятных исключений при обработке файлов.

После проверки того, существует ли ваш файл или нет, вы, скорее всего, захотите прочитать и записать файлы на Java .