Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does 'File.exists' return true, even though 'Files.exists' in the NIO 'Files' class returns false

I am trying to determine if a file exists in a network folder:

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

Using NIO Files:

Files.exists(path) == false

Using File:

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

Using File seems to be the correct one according to our tests. Why does File work better than Files?

So, which is it? Can't be both!

But wait, there is also Files.notExists(path).

When the network share file actually exists

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

When the network share file actually does not exist

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

Another equally insane way of looking at the three results above

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

:smileyFace:

Environment and Comments

The program is running on a Windows 8.1 Pro 32 bit machine (OS and machine) and checking on a network share from a Windows 2008 R2 (32 bit) machine.

To determine that Files.exists was failed, I installed a WatchService to monitor the folder and saw that the file did exist when Files.exists was checking. I then logged as both methods and found File.exists to be the correct one.

Now, in my code I have the check as Files.exists(path) || path.toFile().exists().

Kinda seems stupid to have to do both. Probably could just get away with the later. Just trying to give the engineers over at Oracle the benefit of the doubt, but the whole thing is rather silly that they report different.

Also, I don't care if 'exists' is immediately outdated. I just want to know if the file exists at the instant that we are checking. I've never come across this -- we just spent 30 hours between me and another developer trying to figure out why our programs are not interfacing because of this 'feature'.

Meditate on this a while

File.exists(): Returns true if and only if the file or directory denoted by this abstract pathname exists; false otherwise.

Files.exists(): Returns true if the file exists; false if the file does not exist or its existence cannot be determined.

That cracks me up! "if and only if the file or directory denoted by this abstract pathname exists; false otherwise" is at odds with "true if the file exists; false if the file does not exist or its existence cannot be determined"

So, how still can File.exists be true if "the existence cannot be determined"? Obviously, the existence can be (and is being) determined by File but not by Files.

like image 666
The Coordinator Avatar asked May 29 '15 02:05

The Coordinator


People also ask

Which method of the class returns true if the file exists otherwise returns False?

File exists() method in Java with examples The exists() function is a part of the File class in Java. This function determines whether the is a file or directory denoted by the abstract filename exists or not. The function returns true if the abstract file path exists or else returns false.

What happens if file already exists Java?

If the file name doesn't yet exist, it will work fine. But if the file name already exists, then the user will get the "nameAlreadyExists()" alert dialog but the file will still be added and overwritten.

What is the difference between file and files in Java?

Files is utility class holding static methods for managing file system, File is class which instances represent single path (with few additional methods allowing manipulating this path).


1 Answers

As to why there may be a difference between the two, contrast their documentation:

File.exists(): Returns true if and only if the file or directory denoted by this abstract pathname exists; false otherwise.

Files.exists(): Returns true if the file exists; false if the file does not exist or its existence cannot be determined.

That could possibly explain the difference between the two, perhaps the Files one is having troubles ascertaining the existence of the file.

For example, under Linux, it's possible to set up directory and file permissions in such a way that you can open a file that exists but cannot see that it exists (by taking away read permission on the directory the file is in while leaving the file permissions more open).

As per more of Oracle's documentation, Files.exists() only returns true if the file is verified to exist.

A return value of false does not mean it doesn't exist.

They suggest you use both exists() and notExists() to cover the three possibilities, something like:

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!");

That covers the three possibilities of file state covered in that link above:

  • The file is verified to exist.
  • The file is verified to not exist.
  • The file's status is unknown. This result can occur when the program does not have access to the file.
like image 163
paxdiablo Avatar answered Nov 10 '22 15:11

paxdiablo