Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - check safely if a file exist on a network drive

I want to test if a file exists on a mounted network drive.

I wrote this simple code using File.exists.

import java.io.File;

public class NetworkDrive {
    public static void main(String[] args) {
        System.err.println(new File("/Volumes/DATA/testedFile.txt").exists());
    }
}

It works correctly mostly but i found an edge case where this code is problematic. If the drive was mounted and for some reason the network connection fails down, the program hangs for a very long time (10 minutes).

time java NetworkDrive
false

real    10m6.114s
user    0m0.431s
sys 0m0.949s

Even if i try to kill it using with a KILL signal, the process is still running.

1875 ttys000    0:00.00 (java)

The problem is the same with java.nio:

Files.exists(Paths.get("/Volumes/DATA/testedFile.txt"));

I use java version 1.8.0_20 on OS X Yosemite.

like image 544
gontard Avatar asked Feb 02 '15 13:02

gontard


2 Answers

The File#exists method in java is just a wrapper around a native O/S call which is what is taking that long. My suggestion would be to implement a timeout in your program; assuming that the file does not exist if the call does not return within a shorter time. Simple timeout in java notes a possible way of doing that.

EDIT: The fact that you cannot kill the thread even with a KILL signal shows that the system call is uninterruptible. This is a problem of the O/S and cannot be solved in Java. While it does prevent the program from ending while the call is running (even if you mark the thread as a daemon), you can still work around it by executing the call in another thread: that way, you can assume the call has failed after a shorter timeout in your main thread and carry on with program execution, even if the call is still running in the background.

like image 170
Adrian Leonhard Avatar answered Oct 05 '22 13:10

Adrian Leonhard


The File class relies heavily on the local filesystem without knowing that there is some sort of network behind it. If you want to keep the application responsive you can try to call new File("/Volumes/DATA/testedFile.txt").exists() from another Thread.

Hope this helps.

like image 36
Andrey E Avatar answered Oct 05 '22 13:10

Andrey E