Why does 'File.exists' return true, even though 'Files.exists' in the NIO 'Files' class returns false
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.
Related videos on Youtube
The Coordinator
I am the protagonist in many popular Java-based business and hobby codebase box office hits. As an ambidextrous hard-partying and swinging hippie programmer, I save the world from code bugs and thaw cryogenically frozen greatness from my colleagues tortured and uncompiled source - while writing great code! Not only have I actually met Borat, I also have experience with Java, Groovy, Python, Fortran, QBasic, Bash, DOS and just about anything else required to get the job done in a multidisciplinary, undisciplined and uncouth-although-amazing software environment. My big project will be the Oz programming language. When it materializes, all other programming domains will crumble before the all-powerful, syntactically beautiful and functionally implicit Oz! I suppose I would then be the Wizard of Oz ;-)
Updated on September 16, 2022Comments
-
The Coordinator over 1 year
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 doesFile
work better thanFiles
?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.-
MadProgrammer almost 9 yearsBeware of UNC paths, had a lot of trouble with those, especially on Windows 8
-
Joshua Taylor about 3 years"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." The File.exists() method only works with
File
instances, which denote resources on the filesystem.Files.exists(Path)
works withPath
instances, which can capture (depending on the available FileSystemProviders) things that are not in the filesystem.
-
-
The Coordinator almost 9 yearsActually, it is correct in my code, I just typed it wrong int he example. Thanks for spotting that. Corrected.
-
Jean-François Savard almost 9 yearsThen why would
File#exists
return true ? The documentation specify that "true if and only if the file or directory denoted by this abstract pathname exists; " -
paxdiablo almost 9 yearsHence my wording "which may or may not".
-
The Coordinator almost 9 years@Jean-FrançoisSavard LOL. That's why I am posting the question. Now I am checking everything using 'Files.exists(path) || path.toFile().exists()' :)
-
paxdiablo almost 9 years@Saint, since you've now changed the question to clarify the string you're using has the correct escapes, I've removed the initial section detailing why that was a problem.
-
The Coordinator almost 9 years@paxdiablo So, what you are saying is that: exists = Files.exists(path) || !Files.notExists(path). And that also notExists = Files.notExists(path) || !Files.exists(path). :)
-
Prashant almost 9 yearsYou might want to use LinkOption.NOFOLLOW_LINKS to reduce the number of checks.