I never thought it would happen to me, but I ran into my first bug in Java:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5003595
I'm pretty much in the same exact situation as described in the bug (NFS on linux), and I'm seeing that File.exists() is not returning the correct value (at least not right away).
So my question is, is there any alternative to this method of checking if a file exists? I'd prefer to keep it OS agnostic if possible.
EDIT: I have found a workaround. If you make a call to 'ls $filedir', the NFS refreshes whatever cache/metadata that is giving Java trouble, and File.exists() returns the correct value. Granted, this isn't totally ideal, since it hurts portability, but there are ways to deal with that problem.
Thanks, -Ben
The obvious alternative is File.isFile(). Try that first.
Although it will become inaccurate when reading read-only files you could always use the File.canWrite() to check if the file exists.
If both the above fail you could use the File.length(). If it returns 0L you know that the file does not exists.
What happens if
File.exists()
returns true, then someone deletes the file/your NFS mount goes away, then you try and open the file? Basically,File.exists()
is useless since you need to handle the exceptions that can arise from opening the file anyway.I notice that Java 7's java.nio.file.Path.exists() method returns false if the file doesn't exist or it's existence can't be determined. It would seem, therefore, that false negatives will be around for a while and that your code will need to tolerate them.
The basic problem you have with NFS is that it caches attributes, files and directories information. This means the information can be out of date. You might be able to turn off caching, you will see a significant reduction in performance.
The important thing to remember is that NFS is not a messaging service and is not designed for timely delivery of data.
All
File.exists
tells you is whether the file existed at some point in the past. It doesn't tell you:So try to design your application so it can handle files that don't exist without trying to check for that in advance. (You'll have to handle various exceptions when actually working with the file.)
I experienced the same problem and solved it with a call to
file.getParentFile().list()
. Essentially the same as your solution, but OS agnostic.