Автор оригинала: David Landup.
Вступление
Проверка наличия файла или каталога-простая и важная операция во многих задачах. Перед доступом к файлу мы должны проверить, существует ли он, чтобы избежать исключения NullPointerException
. То же самое касается каталогов.
Хотя некоторые функции могут создавать новый файл/каталог, если запрошенный не существует, это может быть противоположностью тому, что мы хотим. Если мы хотим добавить дополнительную информацию в существующий файл, а метод выполняется без предупреждения, так как он создает необходимый ему новый файл, мы, возможно, потеряли некоторую информацию, не осознавая этого.
Здесь у нас простая структура:
02/13/2020 11:53 AMdirectory 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 .