简体   繁体   English

在 Java 中检测 USB 驱动器

[英]Detect USB Drive in Java

How can I detect when a USB drive is attached to a computer in Windows, Linux, or Mac?如何检测 USB 驱动器何时连接到 Windows、Linux 或 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 (eg File.listRoots() in Linux only returns "/").我在网上看到的唯一方法是迭代驱动器,但我认为没有一个很好的跨平台方法(例如,Linux 中的 File.listRoots() 只返回“/”)。 Even in Windows this would cause problems reading from every device, such as a network drive that takes a long time to access.即使在 Windows 中,这也会导致从每个设备(例如需要很长时间访问的网络驱动器)读取的问题。

There is a library called jUsb that sounds like it accomplishes this in Linux, but it doesn't work in Windows.有一个名为 jUsb 的库,听起来像是在 Linux 中实现了这一点,但它在 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.还有一个名为 jUsb for Windows 的扩展,但这需要用户安装 dll 文件并运行 .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... [编辑] 此外,jUsb 显然不适用于任何最新版本的 Java,所以这甚至不是一个选项......

Thanks谢谢

I've made a small library to detect USB storage devices on Java.我制作了一个小型库来检测 Java 上的 USB 存储设备。 It works on Windows, OSX and Linux.它适用于 Windows、OSX 和 Linux。 Take a look at: https://github.com/samuelcampos/usbdrivedetector看一看: 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.上次我检查没有用于 Java 和 Windows 的开源 USB 库。 The simple hack that I used was to write a small JNI app for capturing WM_DEVICECHANGE event.我使用的简单技巧是编写一个小型 JNI 应用程序来捕获WM_DEVICECHANGE事件。 Following links may help以下链接可能会有所帮助

  1. http://www.codeproject.com/KB/system/DriveDetector.aspx http://www.codeproject.com/KB/system/DriveDetector.aspx
  2. http://msdn.microsoft.com/en-us/library/aa363480(v=VS.85).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/ )如果您不想弄乱 JNI,请使用带有 JNA 的任何 Windows 本机库进行 USB( https://github.com/twall/jna/

altough i would suggest using WM_DEVICECHANGE approach... because your requirement is just a notification message....虽然我建议使用WM_DEVICECHANGE方法...因为您的要求只是一条通知消息....

Check out this code. 看看这段代码。 To fulfill your demands, simply poll to detect the USB drive and continue when you got it. 为了满足您的需求,只需轮询以检测USB驱动器并在获得时继续。

I created the code that works on Linux and windows check this我创建了适用于 Linux 和 Windows 的代码检查这个

 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() .在程序开始时,执行DriverCheck.updateDriverInfo() Then, to check to see if a usb has been plugged in or pulled out, use DriverChecker.driversChangedSinceLastUpdate() (returns boolean ).然后,要检查 USB 是否已插入拔出,请使用DriverChecker.driversChangedSinceLastUpdate() (返回boolean )。

To check if a usb has been inserted, use newDriverDetected() .要检查是否已插入 USB,请使用newDriverDetected() To check if a usb has been removed, use driverRemoved()要检查 USB 是否已被移除,请使用driverRemoved()

This pretty much checks for all disc drives from A:/ to Z:/.这几乎会检查从 A:/ 到 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"));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM