Reputation: 369
I am not sure where to even start I did some googling but I cant find anyhing for java. AI has also been unhelpful
I have treid some code that can dectect a ubs but im not sure about the name
Here is the code I have tried
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();
}
}
Upvotes: 0
Views: 81
Reputation: 44338
Some important notes:
File.listRoots()
will only detect new USB storage devices in Windows. For other operating systems, it is necessary to examine the FileStores.Unfortunately, there is no reliable way to determine the file path for a FileStore, other than looking at the text returned by its toString method on non-Windows systems. The best we can do is hope that the current format of the toString implementation remains stable. (Java SE tends to be good about keeping toString formats stable, even if it’s detrimental; anyone who has passed an array to System.out.println probably knows this.)
So, with that in mind, here is a program that monitors file systems:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileStore;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Set;
import java.util.LinkedHashSet;
import java.util.function.Consumer;
public class FileStores {
public record Root(Path path,
String type,
String device) {
}
public static Collection<Root> listRoots()
throws IOException {
Collection<Root> roots = new LinkedHashSet<>();
FileSystem fs = FileSystems.getDefault();
if (System.getProperty("os.name").contains("Windows")) {
for (Path rootDir : fs.getRootDirectories()) {
String type = Files.getFileStore(rootDir).type();
roots.add(new Root(rootDir, type, null));
}
} else {
for (FileStore store : fs.getFileStores()) {
String summary = store.toString();
String name = store.name();
String type = store.type();
String suffix = " (" + name + ")";
Path mountPath;
if (summary.endsWith(suffix)) {
String mountPoint = summary.substring(0,
summary.length() - suffix.length());
mountPath = Path.of(mountPoint);
} else {
mountPath = null;
}
roots.add(new Root(mountPath, type, name));
}
}
return roots;
}
public static void monitorRoots(Consumer<Collection<Root>> listener)
throws InterruptedException {
Collection<Root> roots = Set.of();
while (true) {
try {
Collection<Root> newRoots = listRoots();
if (!newRoots.equals(roots)) {
roots = newRoots;
listener.accept(new LinkedHashSet<>(roots));
}
} catch (IOException e) {
e.printStackTrace();
}
Thread.sleep(250);
}
}
public static void main(String[] args)
throws IOException {
Runnable monitor = () -> {
try {
monitorRoots(roots -> roots.forEach(System.out::println));
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread monitorThread = new Thread(monitor);
monitorThread.start();
}
}
Notice that there is no catching of InterruptedException inside the loop. If an interrupt occurs, the loop will automatically terminate, which is a good thing. Interrupts don’t happen by accident; if a thread is interrupted, it’s because some other code wanted to shut it down.
I changed the frequency of checks to four times per second. Depending on the nature of your application, it can probably be even less frequent than that.
Upvotes: 1
Reputation: 78835
Do you want to detect all kind of USB devices, or just USB memory stick and similar (aka as USB mass storage devices)?
With the JavaDoesUSB library, you can detect when a USB device has been connected and you can also filter for specific device classes:
import net.codecrete.usb.Usb;
import net.codecrete.usb.UsbDevice;
import java.io.IOException;
public class MassStorage {
public static void main(String[] args) throws IOException {
Usb.setOnDeviceConnected(MassStorage::onConnected);
System.out.println("Press ENTER to exit");
System.in.read();
}
private static void onConnected(UsbDevice device) {
if (isMassStorage(device)) {
System.out.println("Mass storage device connected: " + device);
}
}
private static boolean isMassStorage(UsbDevice device) {
return device.getInterfaces().stream()
.anyMatch(intf -> intf.getCurrentAlternate().getClassCode() == 0x08);
}
}
Upvotes: 0