Почему "File.exists" возвращает true, хотя "Files.exists" в классе NIO "Файлы" возвращает false

Я пытаюсь определить, существует ли файл в сетевой папке:

// File name is "\\QWERTY\folder\dir\A123456.TXT"
Path path = Paths.get("\\\\QWERTY\\folder\\dir\\A123456.TXT")

Использование NIO Files:

Files.exists(path) == false

Использование File:

path.toFile().exists() == true

Использование File кажется правильным в соответствии с нашими тестами. Почему File работает лучше, чем Files?

Итак, что это? Не может быть и двух!

Но подождите, есть также Files.notExists(path).

Когда фактически существует файл сетевого ресурса

Files.exists(path): false
Files.notExists(path): false
path.toFile().exists(): true

Когда сетевой файл общего доступа фактически не существует

Files.exists(path): false
Files.notExists(path): true
path.toFile().exists(): false

Еще один безумный взгляд на три результата выше

boolean exists = Files.exists(path) || !Files.notExists(path)
boolean notExists = Files.notExists(path) || !Files.exists(path)
boolean oldFashionedExists = path.toFile().exists()

: smileyFace:

Окружающая среда и комментарии

Программа работает на 32-разрядной машине Windows 8.1 Pro (ОС и машине) и проверяет общий сетевой ресурс на машине Windows 2008 R2 (32-разрядная версия).

Чтобы определить, что Files.exists не удалось, я установил WatchService для наблюдения за папкой и увидел, что файл существует, когда Files.exists проверял. Затем я зарегистрировался как оба метода и нашел File.exists правильным.

Теперь в моем коде я проверил как Files.exists(path) || path.toFile().exists().

Похоже, что глупо, что нужно делать то и другое. Наверное, можно просто уйти с последним. Просто пытаюсь дать инженерам в Oracle преимущество сомнений, но все это довольно глупо, что они сообщают о разных.

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

Медитируйте это время

File.exists(): возвращает true тогда и только тогда, когда существует файл или каталог, обозначенные этим абстрактным именем пути; false в противном случае.

Files.exists(): возвращает true, если файл существует; false, если файл не существует или его существование не может быть определено.

Это треснет меня! "тогда и только тогда, когда существует файл или каталог, обозначенные этим абстрактным пустым именем; false в противном случае" не соответствует "true, если файл существует; false, если файл не существует или его существование не может быть определено"

Итак, как еще может File.exists быть истинным, если "существование не может быть определено"? Очевидно, что существование может быть (и находится) определено файлом, но не файлами.

Ответ 1

Относительно того, почему существует разница между ними, сравните их документацию:

File.exists(): возвращает true тогда и только тогда, когда существует файл или каталог, обозначенные этим абстрактным именем пути; false в противном случае.

Files.exists(): возвращает true, если файл существует; false, если файл не существует или его существование не может быть определено.

Возможно, это объясняет разницу между двумя, возможно, Files имеет проблемы с констатацией существования файла.

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

По больше документации Oracle, Files.exists() возвращает true, если файл проверен на существование.

Возвращаемое значение false не означает, что оно не существует.

Они предлагают использовать как exists(), так и notExists() для покрытия трех возможностей, например:

if (Files.exists(fspec)) {
    System.out.println("It exists!");
else if (Files.notExists(fspec)) {
    System.out.println("It does not exist!");
else
    System.out.println("I have no idea!");

Это охватывает три возможности состояния файла, указанные в этой ссылке выше:

  • Файл проверен на существование.
  • Файл не проверен.
  • Состояние файла неизвестно. Этот результат может возникнуть, когда программа не имеет доступа к файлу.

Ответ 2

У меня была такая же проблема, но ваш хак мне не помог. Когда файл фактически существовал, все методы вернули мне false:

Files.exists(path) = false, 
path.toFile().exists() = false, 
Files.notExists(path) = true, 
Files.exists(path) || path.toFile().exists() = false

Но если в данный момент в проводнике был открыт сетевой каталог с этим файлом, то его существование было правильно обработано

Я решил эту проблему, создав новый файл в каталоге (затем удаляю его):

Files.createFile(Paths.get(path.getParent().toString(), "test"));

После этой команды, по-видимому, Windows обновляет информацию о папке