Checking for an existing file using any available method is usually very fast, but if the file path includes an inaccessible (network) drive, the check takes several seconds.
Checking for a non-existent drive is no problem ("R:" in the code sample), but checking a known drive that is no longer accessible ("S:" in the code sample) takes very long time.
Edit: this has a significant effect both when validating a list of recent files (multiply each inaccessible file by 2-4 seconds) and when opening the standard JFileChooser(), which can take 1-2 minutes with a few disconnected drives.
Questions:
- Is this a known problem?
- Is there a workaround?
Context: Java 11 or 17 on Windows 10 with an existing "C:" drive, a non-existent "R:" drive, and a network drive "S:" that is not accessible.
Sample code:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
public class FileSystemExperiment {
private static final String[] FILES = {
System.getProperty("user.home"), // home dir exists
"/no/such/file", // missing file on current drive
"C:\\no\\such\\file", // missing file on existing drive
"R:\\", // an unknown drive
"S:\\", // a known but inaccessible drive
};
private static long started;
private static void exists(String... pathStrings) {
for (String pathString : pathStrings) {
File file = new File(pathString);
Path path = file.toPath();
System.out.printf("%nFile '%s' ...%n", file);
started = System.currentTimeMillis();
time("file.exists()", file.exists());
time("file.lastModified()>0", file.lastModified() > 0);
time("Files.exists(path)", Files.exists(path));
time("Files.readAttributes(path)", readAttributes(path) != null);
}
}
private static void time(String msg, boolean exists) {
System.out.printf("%-30s | %-5s | time=%s ms%n", msg, exists, System.currentTimeMillis() - started);
started = System.currentTimeMillis();
}
private static BasicFileAttributes readAttributes(Path path) {
try {
return Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
}
catch (IOException e) {
return null;
}
}
public static void main(String[] args) {
exists(FILES);
}
}
Output:
File 'C:\Users\p2r' ...
file.exists() | true | time=1 ms
file.lastModified()>=0 | true | time=0 ms
Files.exists(path) | true | time=2 ms
Files.readAttributes(path) | true | time=0 ms
File '\no\such\file' ...
file.exists() | false | time=0 ms
file.lastModified()>=0 | false | time=0 ms
Files.exists(path) | false | time=1 ms
Files.readAttributes(path) | false | time=0 ms
File 'C:\no\such\file' ...
file.exists() | false | time=0 ms
file.lastModified()>=0 | false | time=0 ms
Files.exists(path) | false | time=1 ms
Files.readAttributes(path) | false | time=1 ms
File 'R:\' ...
file.exists() | false | time=0 ms
file.lastModified()>=0 | false | time=0 ms
Files.exists(path) | false | time=0 ms
Files.readAttributes(path) | false | time=0 ms
File 'S:\' ...
file.exists() | false | time=7802 ms
file.lastModified()>=0 | false | time=10067 ms
Files.exists(path) | false | time=7171 ms
Files.readAttributes(path) | false | time=10047 ms