I am working on a Java program that requires to check the existence of files.
Well, simple enough, the code make use calls to File.exists()
for checking file existence. And the problem I have is, it reports false positive. That means the file does not actually exist but exists()
method returns true
. No exception was captured (at least no exception like "Stale NFS handle"). The program even managed to read the file through InputStream
, getting 0 bytes as expected and yet no exception. The target directory is a Linux NFS. And I am 100% sure that the file being looked for never exists.
I know there are known bugs (kind of API limitation) exist for java.io.File.exists()
. So I've then added another way round by checking file existence using Linux command ls
. Instead of making call to File.exists()
the Java code now runs a Linux command to ls
the target file. If exit code is 0
, file exists. Otherwise, file does not exist.
The number of times the issue is hit seems to be reduced with the introduction of the trick, but still pops. Again, no error was captured anywhere (stdout this time). That means the problem is so serious that even native Linux command won't fix for 100% of the time.
So there are couple of questions around:
File.exists()
is about reporting false negative. Where file was reported to not exist but in fact does exist. As the API does not throws IOException
for File.exists()
, it choose to swallow the Exception in the case calls to OS's underlying native functions failed e.g. NFS timeout. But then this does not explain the false positive case I am having, given that the file never exist. Any throw on this one?ls
exit code is, 0
means okay, equivalent to file exists. Is this understanding wrong? The man page of ls
is not so clear on explaining the meaning of exit code: Exit status is 0
if OK, 1
if minor problems, 2
if serious trouble.JDK7 was released a few months ago. There are exists
and notExists
methods in the Files
class but they return a boolean
rather than throwing an exception. If you really want an exception then use FileSystems.getDefault().provider().checkAccess(path)
and it will throw an exception if the file does not exist.