Detect USB Drive in Java
How can I detect when a USB drive is attached to a computer in Windows, Linux, or Mac?
The only way I have seen online to do this is to iterate the drives, but I don't think there is a very good way to do that cross-platform (e.g. File.listRoots() in Linux only returns "/"). Even in Windows this would cause problems reading from every device, such as a network drive that takes a long time to access.
There is a library called jUsb that sounds like it accomplishes this in Linux, but it doesn't work in Windows. There is also an extension to this called jUsb for Windows, but that requires users to install a dll file and run a .reg. Neither of these seem to be developed for several years, so I'm hoping a better solution exists now. They're also overkill for 开发者_如何学运维what I need, when I only want to detect if a device is connected that contains a file I need.
[Edit] Furthermore, jUsb apparently doesn't work with any recent version of Java, so this isn't even an option...
Thanks
I've made a small library to detect USB storage devices on Java. It works on Windows, OSX and Linux. Take a look at: https://github.com/samuelcampos/usbdrivedetector
public class AutoDetect {
static File[] oldListRoot = File.listRoots();
public static void main(String[] args) {
AutoDetect.waitForNotifying();
}
public static void waitForNotifying() {
Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (File.listRoots().length > oldListRoot.length) {
System.out.println("new drive detected");
oldListRoot = File.listRoots();
System.out.println("drive"+oldListRoot[oldListRoot.length-1]+" detected");
} else if (File.listRoots().length < oldListRoot.length) {
System.out.println(oldListRoot[oldListRoot.length-1]+" drive removed");
oldListRoot = File.listRoots();
}
}
}
});
t.start();
}
}
Last time I checked there were no open source USB library for java and in windows. The simple hack that I used was to write a small JNI app for capturing WM_DEVICECHANGE
event. Following links may help
- http://www.codeproject.com/KB/system/DriveDetector.aspx
- http://msdn.microsoft.com/en-us/library/aa363480(v=VS.85).aspx
In case you don't want to mess with the JNI then use any windows native library for USB with JNA ( https://github.com/twall/jna/ )
altough i would suggest using WM_DEVICECHANGE
approach... because your requirement is just a notification message....
I created the code that works on Linux and windows check this
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main{
public static void main(String[] args) throws IOException{//main class
Main m = new Main();//main method
String os = System.getProperty("os.name").toLowerCase();//get Os name
if(os.indexOf("win") > 0){//checking if os is *nix or windows
//This is windows
m.ListFiles(new File("/storage"));//do some staf for windows i am not so sure about '/storage' in windows
//external drive will be found on
}else{
//Some *nix OS
//all *nix Os here
m.ListFiles(new File("/media"));//if linux removable drive found on media
//this is for Linux
}
}
void ListFiles(File fls)//this is list drives methods
throws IOException {
while(true){//while loop
try {
Thread.sleep(5000);//repeate a task every 5 minutes
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Process p = Runtime.getRuntime().exec("ls "+fls);//executing command to get the output
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));//getting the output
String line;//output line
while((line = br.readLine()) != null){//reading the output
System.out.print("removable drives : "+line+"\n");//printing the output
}
/*You can modify the code as you wish.
* To check if external storage drivers pluged in or removed, compare the lenght
* Change the time interval if you wish*/
}
}
}
I wrote this program. At the beginning of the program, do DriverCheck.updateDriverInfo()
. Then, to check to see if a usb has been plugged in or pulled out, use DriverChecker.driversChangedSinceLastUpdate()
(returns boolean
).
To check if a usb has been inserted, use newDriverDetected()
. To check if a usb has been removed, use driverRemoved()
This pretty much checks for all disc drives from A:/ to Z:/. Half of them can't even exist, but I check for all of them anyways.
package security;
import java.io.File;
public final class DriverChecker {
private static boolean[] drivers = new boolean[26];
private DriverChecker() {
}
public static boolean checkForDrive(String dir) {
return new File(dir).exists();
}
public static void updateDriverInfo() {
for (int i = 0; i < 26; i++) {
drivers[i] = checkForDrive((char) (i + 'A') + ":/");
}
}
public static boolean newDriverDetected() {
for (int i = 0; i < 26; i++) {
if (!drivers[i] && checkForDrive((char) (i + 'A') + ":/")) {
return true;
}
}
return false;
}
public static boolean driverRemoved() {
for (int i = 0; i < 26; i++) {
if (drivers[i] && !checkForDrive((char) (i + 'A') + ":/")) {
return true;
}
}
return false;
}
public static boolean driversChangedSinceLastUpdate() {
for (int i = 0; i < 26; i++) {
if (drivers[i] != checkForDrive((char) (i + 'A') + ":/")) {
return true;
}
}
return false;
}
public static void printInfo() {
for (int i = 0; i < 26; i++) {
System.out.println("Driver " + (char) (i + 'A') + ":/ "
+ (drivers[i] ? "exists" : "does not exist"));
}
}
}
精彩评论