如何在Java中检测USB插入并获取USB设备名称
Java检测USB设备并获取设备名称
现有代码的局限
你当前的代码通过对比File.listRoots()返回的盘符数组长度变化,能检测到USB设备的插拔,但仅能获取盘符路径(如D:\),无法拿到设备的友好名称(如“我的U盘”)——因为Java标准库的File类没有提供获取设备名称的API。
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(); } File[] currentRoots = File.listRoots(); if (currentRoots.length > oldListRoot.length) { System.out.println("检测到新驱动器"); oldListRoot = currentRoots; System.out.println("驱动器 " + oldListRoot[oldListRoot.length-1] + " 已连接"); } else if (currentRoots.length < oldListRoot.length) { System.out.println("驱动器 " + oldListRoot[oldListRoot.length-1] + " 已移除"); oldListRoot = currentRoots; } } } }); t.start(); } }
解决方案
方法一:使用JNA调用系统原生API(跨平台)
JNA可以直接调用Windows、Linux、macOS的系统API获取设备信息,无需编写JNI代码。
步骤1:添加JNA依赖
如果使用Maven,在pom.xml中添加:
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>
步骤2:实现Windows下的设备名称获取
import com.sun.jna.Native; import com.sun.jna.platform.win32.IntByReference; import com.sun.jna.win32.W32APIOptions; import java.io.File; import java.util.HashMap; import java.util.Map; public class UsbDeviceDetector { public interface Kernel32 extends com.sun.jna.platform.win32.WinNT { Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, W32APIOptions.DEFAULT_OPTIONS); boolean GetVolumeInformation(String lpRootPathName, char[] lpVolumeNameBuffer, int nVolumeNameSize, IntByReference lpVolumeSerialNumber, IntByReference lpMaximumComponentLength, IntByReference lpFileSystemFlags, char[] lpFileSystemNameBuffer, int nFileSystemNameSize); } // 获取盘符对应的设备名称 public static String getVolumeName(String driveLetter) { char[] volumeName = new char[256]; Kernel32.INSTANCE.GetVolumeInformation(driveLetter, volumeName, volumeName.length, null, null, null, null, 0); return Native.toString(volumeName).trim(); } public static void main(String[] args) { File[] roots = File.listRoots(); Map<String, String> driveMap = new HashMap<>(); for (File root : roots) { String drivePath = root.getAbsolutePath(); String volumeName = getVolumeName(drivePath); driveMap.put(drivePath, volumeName); System.out.println("盘符: " + drivePath + " 设备名称: " + volumeName); } } }
步骤3:结合原有检测逻辑
将上述getVolumeName()方法融入你的检测代码,在检测到新盘符时调用该方法即可获取设备名称。
方法二:调用系统命令(无第三方依赖)
如果不想引入JNA,可以直接调用各平台的系统命令解析输出结果:
Windows平台:调用wmic命令
import java.io.BufferedReader; import java.io.InputStreamReader; public class WindowsUsbInfo { public static String getUsbDeviceName(String driveLetter) { try { Process process = Runtime.getRuntime().exec("wmic logicaldisk where DeviceID='" + driveLetter + "' get VolumeName /value"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { if (line.startsWith("VolumeName=")) { return line.substring(11).trim(); } } } catch (Exception e) { e.printStackTrace(); } return ""; } }
Linux平台:调用lsblk命令
import java.io.BufferedReader; import java.io.InputStreamReader; public class LinuxUsbInfo { public static String getUsbDeviceName(String drivePath) { // drivePath格式如 /media/username/MyUSB try { Process process = Runtime.getRuntime().exec("lsblk -no LABEL " + drivePath); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); return reader.readLine().trim(); } catch (Exception e) { e.printStackTrace(); } return ""; } }
macOS平台:调用diskutil命令
import java.io.BufferedReader; import java.io.InputStreamReader; public class MacUsbInfo { public static String getUsbDeviceName(String drivePath) { try { Process process = Runtime.getRuntime().exec("diskutil info " + drivePath + " | grep VolumeName"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = reader.readLine(); if (line != null) { return line.split(":")[1].trim(); } } catch (Exception e) { e.printStackTrace(); } return ""; } }
内容的提问来源于stack exchange,提问作者Tijil Saka
相关产品推荐
相关产品推荐

