Is there a platform-independent way with Java to detect the type of drive a file is located on? Basically I'm interested to distinguish between: hard disks, removable drives (like USB sticks) and network shares. JNI/JNA solutions won't be helpful. Java 7 can be assumed.
You could execute cmd using Java with:
fsutil fsinfo drivetype {drive letter}
The result will give you something like this:
C: - Fixed Drive
D: - CD-ROM Drive
E: - Removable Drive
P: - Remote/Network Drive
Here is a Gist which shows how to determine this using net use
: https://gist.github.com/digulla/31eed31c7ead29ffc7a30aaf87131def
Most important part of the code:
public boolean isDangerous(File file) {
if (!IS_WINDOWS) {
return false;
}
// Make sure the file is absolute
file = file.getAbsoluteFile();
String path = file.getPath();
// System.out.println("Checking [" + path + "]");
// UNC paths are dangerous
if (path.startsWith("//")
|| path.startsWith("\\\\")) {
// We might want to check for \\localhost or \\127.0.0.1 which would be OK, too
return true;
}
String driveLetter = path.substring(0, 1);
String colon = path.substring(1, 2);
if (!":".equals(colon)) {
throw new IllegalArgumentException("Expected 'X:': " + path);
}
return isNetworkDrive(driveLetter);
}
/** Use the command <code>net</code> to determine what this drive is.
* <code>net use</code> will return an error for anything which isn't a share.
*
* <p>Another option would be <code>fsinfo</code> but my gut feeling is that
* <code>net</code> should be available and on the path on every installation
* of Windows.
*/
private boolean isNetworkDrive(String driveLetter) {
List<String> cmd = Arrays.asList("cmd", "/c", "net", "use", driveLetter + ":");
try {
Process p = new ProcessBuilder(cmd)
.redirectErrorStream(true)
.start();
p.getOutputStream().close();
StringBuilder consoleOutput = new StringBuilder();
String line;
try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
while ((line = in.readLine()) != null) {
consoleOutput.append(line).append("\r\n");
}
}
int rc = p.waitFor();
// System.out.println(consoleOutput);
// System.out.println("rc=" + rc);
return rc == 0;
} catch(Exception e) {
throw new IllegalStateException("Unable to run 'net use' on " + driveLetter, e);
}
}
The FileSystemView
class from Swing has some functionality to support detecting the type of the drive (cf isFloppyDrive
, isComputerNode
). I'm afraid there's no standard way to detect if a drive is connected through USB though.
Contrived, untested example:
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;
....
JFileChooser fc = new JFileChooser();
FileSystemView fsv = fc.getFileSystemView();
if (fsv.isFloppyDrive(new File("A:"))) // is A: a floppy drive?
In JDK 7 there's another option. I haven't used it, but the FileStore
API has a type
method. The documentation says that:
The format of the string returned by this method is highly implementation specific. It may indicate, for example, the format used or if the file store is local or remote.
Apparently the way to use it would be this:
import java.nio.*;
....
for (FileStore store: FileSystems.getDefault().getFileStores()) {
System.out.printf("%s: %s%n", store.name(), store.type());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With