java监听usb记录

  1. 需求:实现通过java监听usb移动介质的拔插和拷贝记录;
    找了很多软件似乎都能实现这个功能,近期公司有这个需求要融到自己的系统板块中,如何能够获取移动介质的相关信息和拷入拷出记录呢?
    这个记录包含从哪个文件的路径地址。
    能不能有同志提供个思路或者方法的

参考GPT和自己的思路:要实现通过Java监听USB移动介质的拔插和拷贝记录,可以使用JNotify库。这个库可以监听文件系统的变化,并通知监听者。具体来说,可以使用JNotify监听USB移动介质的挂载和卸载事件,以及文件的创建、修改、删除等事件。然后根据这些事件的信息记录拷入拷出的记录。

以下是一个基本的示例代码,它使用JNotify库监听指定目录的文件变化:

import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyListener;

public class USBListener {
    public static void main(String[] args) throws Exception {
        // 监听的目录
        String path = "D:\\";
        // 监听的事件类型
        int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
        // 是否监听子目录
        boolean watchSubtree = true;

        // 创建监听器
        JNotifyListener listener = new JNotifyListener() {
            public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
                System.out.println("renamed " + rootPath + " : " + oldName + " -> " + newName);
            }

            public void fileModified(int wd, String rootPath, String name) {
                System.out.println("modified " + rootPath + " : " + name);
            }

            public void fileDeleted(int wd, String rootPath, String name) {
                System.out.println("deleted " + rootPath + " : " + name);
            }

            public void fileCreated(int wd, String rootPath, String name) {
                System.out.println("created " + rootPath + " : " + name);
            }
        };

        // 开始监听
        int watchId = JNotify.addWatch(path, mask, watchSubtree, listener);

        // 等待用户输入,结束监听
        System.in.read();
        JNotify.removeWatch(watchId);
    }
}


这个示例代码会监听指定目录的文件创建、删除、修改和重命名事件,并将这些事件的信息打印到控制台。你可以根据这些事件的信息来记录拷入拷出的记录。

如果你需要获取移动介质的相关信息,比如移动介质的序列号、容量、文件系统等,可以使用Java的File类和FileSystem类。具体来说,可以使用File类来表示移动介质的根目录,然后使用FileSystem类来获取移动介质的相关信息。以下是一个示例代码,它可以列出所有的移动介质,并获取它们的容量和文件系统类型:

import java.io.File;
import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

public class USBWatcher {
public static void main(String[] args) throws IOException {
    File[] roots = File.listRoots();
    for (File root : roots) {
        if (isUSB(root)) {
            System.out.println("USB found: " + root.getPath());
            System.out.println("Capacity: " + getCapacity(root));
            System.out.println("File system type: " + getFileSystemType(root));
        }
    }
}

private static boolean isUSB(File root) throws IOException {
    String type = Files.getFileStore(root.toPath()).type();
    return type.equals("vfat") || type.equals("exfat") || type.equals("ntfs");
}

private static String getFileSystemType(File root) throws IOException {
    return Files.getFileStore(root.toPath()).type();
}

private static long getCapacity(File root) throws IOException {
    Path path = root.toPath();
    FileStore store = Files.getFileStore(path);
    return store.getTotalSpace();
}
}

注意:需要在程序中添加文件系统权限,否则可能无法获取移动介质的相关信息。

该回答引用于gpt与OKX安生共同编写:
  • 该回答引用于gpt与OKX安生共同编写:

要实现通过 Java 监听 USB 移动介质的拔插和拷贝记录,你可以使用 JNA(Java Native Access) 库来调用 Windows API 完成相关操作。具体步骤如下:

  • 导入 JNA 库的依赖。
  • 使用 JNA 提供的接口函数注册 USB 设备插入和移除的回调事件。
  • 实现回调函数,在 USB 设备插入和移除时获取并输出相关信息。
  • 使用 JNA 调用 Windows API 函数来监控文件系统更改,并在拷贝文件时获取并输出相关信息。

用于监听 USB 移动介质的插拔和文件拷贝记录代码:

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.PVOID;
import com.sun.jna.platform.win32.WinUser.WndProc;
import com.sun.jna.win32.W32APIOptions;

public class USBMonitor {

    // 定义 Windows API 的库名称和函数声明
    private static final String USER32 = "user32";
    private static final String KERNEL32 = "kernel32";

    // Windows API 函数声明
    public interface User32 extends W32APIOptions {
        User32 INSTANCE = (User32) Native.loadLibrary(USER32, User32.class, DEFAULT_OPTIONS);
        int RegisterDeviceNotificationW(HWND hRecipient, PVOID NotificationFilter, int Flags);
        boolean UnregisterDeviceNotification(HANDLE Handle);
    }

    public interface Kernel32 extends W32APIOptions {
        Kernel32 INSTANCE = (Kernel32) Native.loadLibrary(KERNEL32, Kernel32.class, DEFAULT_OPTIONS);
        HANDLE CreateFileW(String lpFileName, int dwDesiredAccess, int dwShareMode, PVOID lpSecurityAttributes,
                           int dwCreationDisposition, int dwFlagsAndAttributes, HANDLE hTemplateFile);
        boolean ReadDirectoryChangesW(HANDLE hDirectory, PVOID lpBuffer, int nBufferLength, boolean bWatchSubtree,
                                      int dwNotifyFilter, int[] lpBytesReturned, PVOID lpOverlapped,
                                      PVOID lpCompletionRoutine);
    }

    // 回调函数,当 USB 设备插入或移除时被调用
    public static LRESULT CALLBACK DeviceChangeCallback(int nCode, WPARAM wParam, LPARAM lParam) {
        if (nCode == 0) {
            switch (wParam.intValue()) {
                case 0x8000:  // DBT_DEVICEARRIVAL
                    System.out.println("USB device inserted.");
                    break;
                case 0x8004:  // DBT_DEVICEREMOVECOMPLETE
                    System.out.println("USB device removed.");
                    break;
            }
        }
        return User32.INSTANCE.CallNextHookEx(null, nCode, wParam, lParam);
    }

    public static void main(String[] args) throws Exception {
        // 注册 USB 设备插入和移除的回调事件
        HWND hWnd = new HWND();
        hWnd.setPointer(Pointer.NULL);
        HANDLE hDevNotify = User32.INSTANCE.RegisterDeviceNotificationW(hWnd, null, 0);
        WndProc wndProc = new WndProc() {
            @Override
            public LRESULT callback(HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam) {
                return DeviceChangeCallback(uMsg, wParam, lParam);
            }
        };
        User32.INSTANCE.SetWindowLongPtrW(hWnd, -4, new Pointer(Native.getComponentPointer(wndProc)));

        // 监控文件系统更改
        HANDLE hDir = Kernel32.INSTANCE.CreateFileW("C:\\", 1, 7, null, 3, 128, null);
        byte[] buffer = new byte[4096];
        int[] bytesReturned = new int[1];
        while (true) {
            Kernel32.INSTANCE.ReadDirectoryChangesW(hDir, buffer, buffer.length, true, 0x10 | 0x20 | 0x40 | 0x100,
                                                     bytesReturned, null, null);
            // 在拷贝文件时获取并输出相关信息
            // TODO: 解析 buffer 中的数据,提取拷贝记录
        }
    }
}

实现通过java监听usb移动介质的拔插和拷贝记录,可以采用以下思路和方法:

  1. 使用Java的JNA库调用Windows API来获取移动介质的相关信息和拷贝记录。

  2. 使用Java的JUSB库监听USB移动介质的拔插事件。

  3. 使用Java的IO库实现拷贝记录的读写操作。

该回答引用GPTᴼᴾᴱᴺᴬᴵ,具体如下:
要实现通过 Java 监听 USB 移动介质的拔插和拷贝记录,你可以使用 Java 的 JNA 库和 Win32 API 来实现。具体步骤如下:

1.引入 JNA 库
在 Java 项目中引入 JNA 库,可以通过 Maven 等方式引入。

2.调用 Win32 API
使用 JNA 库调用 Win32 API 来实现对 USB 移动介质的监听。具体可以调用以下函数:

// 获取设备接口信息
boolean SetupDiEnumDeviceInterfaces(Pointer hDevInfo, Pointer devInfo, Guid.GUID interfaceClassGuid, int memberIndex, SP_DEVICE_INTERFACE_DATA.ByReference deviceInterfaceData);

// 获取设备接口详细信息
boolean SetupDiGetDeviceInterfaceDetail(Pointer hDevInfo, SP_DEVICE_INTERFACE_DATA.ByReference deviceInterfaceData, Pointer deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, IntByReference requiredSize, Pointer deviceInfoData);

// 获取设备信息
boolean SetupDiGetDeviceRegistryProperty(Pointer hDevInfo, SP_DEVINFO_DATA.ByReference devInfoData, int property, IntByReference propertyRegDataType, Pointer propertyBuffer, int propertyBufferSize, IntByReference requiredSize);

// 注册设备通知
HDEVNOTIFY RegisterDeviceNotification(HWND hRecipient, Pointer notificationFilter, int flags);

// 注销设备通知
boolean UnregisterDeviceNotification(Pointer hDevNotify);

3.处理 USB 设备拔插事件
监听到 USB 设备拔插事件后,可以调用以下函数来获取设备信息:

// 获取驱动器列表
Kernel32.INSTANCE.GetLogicalDriveStrings(bufferSize, lpBuffer);

// 获取驱动器类型
Kernel32.INSTANCE.GetDriveType(driveRoot);

4.处理拷贝记录
可以使用 Java 的 WatchService 来监听文件的创建、修改、删除事件,从而获取文件的拷贝记录。

至于如何将这些信息融合到你的系统板块中,可以根据具体的需求和系统架构来设计实现方式。


如果以上回答对您有所帮助,望采纳~谢谢

要实现通过Java监听USB移动介质的拔插和拷贝记录,可以使用Java的JNA库来调用操作系统的API函数。

首先,需要在Java中加载Windows系统的动态链接库(dll),如Kernel32.dll和User32.dll。然后,可以使用JNA提供的NativeLibrary类和Function类来调用这些API函数。

监听USB移动介质的拔插可以使用Windows系统提供的RegisterDeviceNotification函数和WM_DEVICECHANGE消息。调用RegisterDeviceNotification函数可以注册一个设备通知句柄,当插入或拔出USB移动介质时,Windows会发送WM_DEVICECHANGE消息到该句柄。通过监听WM_DEVICECHANGE消息,可以获取到USB移动介质的相关信息。

拷贝记录可以使用Java的File类和操作系统的API函数来实现。通过监听USB移动介质的插拔事件,可以获取到USB移动介质的盘符,然后可以使用File类来访问该盘符下的文件和文件夹。可以使用Java的File类的API函数,如listFiles和isDirectory来获取目录下的文件和子目录。对于拷贝事件,可以使用Java的File类的API函数,如lastModified来获取文件的最后修改时间,记录到日志中即可。

需要注意的是,不同的操作系统有不同的API函数和调用方式,需要根据操作系统的不同进行适当的修改。

针对您的需求,可以使用Java提供的USB监听器来监听USB设备的插拔事件,进而实现对移动介质的拔插记录。具体的实现方式可以参考以下步骤:

1.创建USB监听器

可以通过Java提供的UsbServices来创建USB监听器,代码示例如下:

UsbServices services = UsbHostManager.getUsbServices();
UsbHub root = services.getRootUsbHub();
UsbDevice device = findDevice(root, vendorId, productId);
UsbDeviceConnection connection = device.open();
UsbInterface iface = device.getInterface(0);
UsbEndpoint endpoint = iface.getEndpoint(0);
UsbPipe pipe = endpoint.getUsbPipe();
pipe.open();

2.实现USB插拔事件监听器

可以实现UsbServices中的UsbServicesListener接口来监听USB设备的插拔事件,代码示例如下:

services.addUsbServicesListener(new UsbServicesListener() {
    @Override
    public void usbDeviceAttached(UsbDevice device) {
        // 处理设备插入事件
    }

    @Override
    public void usbDeviceDetached(UsbDevice device) {
        // 处理设备拔出事件
    }
});

3.获取移动介质相关信息和拷贝记录

当USB设备插入时,可以通过UsbDevice对象获取到移动介质的相关信息,例如设备的路径、厂商、产品等信息。当移动介质进行拷入拷出操作时,可以使用Java提供的文件操作API来记录拷贝记录,例如记录拷贝的文件路径地址等信息。

综上所述,通过以上的步骤可以实现通过Java监听USB移动介质的拔插和拷贝记录,并且可以通过Java提供的文件操作API来获取相关信息。希望能够对您有所帮助!

pom.xml

        <dependency>
            <groupId>com.sun.jna</groupId>
            <artifactId>jna</artifactId>
            <version>3.0.9</version>
        </dependency>
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna-platform</artifactId>
            <version>5.13.0</version>
        </dependency>

代码:

import com.sun.jna.Pointer;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;

import java.util.Arrays;
import java.util.List;

public class USBWatcher {

    public interface User32 extends StdCallLibrary {
        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);

        interface WNDENUMPROC extends StdCallCallback {
            boolean callback(Pointer hWnd, Pointer arg);
        }

        boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg);

        int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount);

        WinDef.HWND FindWindow(String lpClassName, String lpWindowName);

        int SendMessageA(WinDef.HWND hWnd, int msg, int wParam, byte[] lParam);
    }

    public interface Kernel32 extends StdCallLibrary {
        Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

        WinNT.HANDLE FindFirstVolume(byte[] lpszVolumeName, int cchBufferLength);

        boolean FindNextVolume(WinNT.HANDLE hFindVolume, byte[] lpszVolumeName, int cchBufferLength);

        boolean FindVolumeClose(WinNT.HANDLE hFindVolume);

        boolean GetVolumePathNamesForVolumeName(String lpszVolumeName, byte[] lpszVolumePathNames, int cchBufferLength, IntByReference lpcchReturnLength);

        WinNT.HANDLE CreateFile(String lpFileName, int dwDesiredAccess, int dwShareMode, Pointer lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, WinNT.HANDLE hTemplateFile);

        boolean DeviceIoControl(WinNT.HANDLE hDevice, int dwIoControlCode, Pointer lpInBuffer, int nInBufferSize, Pointer lpOutBuffer, int nOutBufferSize, IntByReference lpBytesReturned, Pointer lpOverlapped);

        boolean CloseHandle(WinNT.HANDLE hObject);
    }

    public static final int DBT_DEVICEARRIVAL = 0x8000;
    public static final int DBT_DEVICEREMOVECOMPLETE = 0x8004;
    public static final int DBT_DEVTYP_VOLUME = 0x00000002;
    public static final int WM_DEVICECHANGE = 0x0219;
    public static final int FILE_SHARE_READ = 0x00000001;
    public static final int FILE_SHARE_WRITE = 0x00000002;
    public static final int FILE_SHARE_DELETE = 0x00000004;
    public static final int OPEN_EXISTING = 3;
    public static final int GENERIC_READ = 0x80000000;
    public static final int GENERIC_WRITE = 0x40000000;
    public static final int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;

    public static void main(String[] args) {
        User32 user32 = User32.INSTANCE;
        Kernel32 kernel32 = Kernel32.INSTANCE;

        User32.WNDENUMPROC enumProc = new User32.WNDENUMPROC() {
            @Override
            public boolean callback(Pointer hWnd, Pointer arg) {
                byte[] windowText = new byte[512];
                user32.GetWindowTextA(hWnd, windowText, 512);
                String wText = Native.toString(windowText);
                if (wText.contains("Device Notification")) {
                    WinDef.HWND hDevNotifyWnd = new WinDef.HWND(hWnd);
                    int nMsg = WM_DEVICECHANGE;
                    int wParam = DBT_DEVICEARRIVAL | DBT_DEVICEREMOVECOMPLETE;
                    int lParam = DBT_DEVTYP_VOLUME;
                    user32.SendMessageA(hDevNotifyWnd, nMsg, wParam, new byte[]{Integer.valueOf(lParam).byteValue()});
                }
                return true;
            }
        };
        user32.EnumWindows(enumProc, null);

        byte[] lpszVolumeName = new byte[1024];
        WinNT.HANDLE hFindVolume = kernel32.FindFirstVolume(lpszVolumeName, 1024);
        while (kernel32.FindNextVolume(hFindVolume, lpszVolumeName, 1024)) {
            String volumeName = Native.toString(lpszVolumeName).replaceAll("\\\\.$", "");
            byte[] lpszVolumePathNames = new byte[1024];
            IntByReference lpcchReturnLength = new IntByReference();
            kernel32.GetVolumePathNamesForVolumeName(volumeName, lpszVolumePathNames, 1024, lpcchReturnLength);
            String[] volumePathNames = Native.toString(lpszVolumePathNames).split("\\\\");
            String driveLetter = volumePathNames[0];
            WinNT.HANDLE hDevice = kernel32.CreateFile("\\\\.\\" + driveLetter, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, null, OPEN_EXISTING, 0, null);
            IntByReference lpBytesReturned = new IntByReference();
            STORAGE_DEVICE_NUMBER storageDeviceNumber = new STORAGE_DEVICE_NUMBER();
            kernel32.DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, null, 0, storageDeviceNumber.getPointer(), storageDeviceNumber.size(), lpBytesReturned, null);
            kernel32.CloseHandle(hDevice);
            System.out.println("USB device inserted: " + driveLetter + ", DeviceNumber: " + storageDeviceNumber.DeviceNumber);
        }
        kernel32.FindVolumeClose(hFindVolume);
    }

    public static class STORAGE_DEVICE_NUMBER extends Structure {
        public int DeviceType;
        public int DeviceNumber;
        public int PartitionNumber;

        public static class ByReference extends STORAGE_DEVICE_NUMBER implements Structure.ByReference {
        }

        public static class ByValue extends STORAGE_DEVICE_NUMBER implements Structure.ByValue {
        }

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("DeviceType", "DeviceNumber", "PartitionNumber");
        }
    }
}


很简单啊


public void xprotolab() throws USBException, IOException {
     USB usb = new USB();
     for (USBDevice device : usb.devices()) {
         if (device.vendor() == 0x16d0 && device.product() == 0x06f9) {
             System.out.println("Found XScope: " + device);
             for (USBConfiguration config : device.configurations()) {
                 try (USBOpenDevice openDevice = device.open()) {
                     System.out.println("Activating " + config);
                     openDevice.activate(config);
                     for (USBInterface iface : config.interfaces()) {
                         System.out.println(iface);
                         openDevice.claim(iface);
                         for (USBInterfaceDescriptor ifaceDescriptor : iface.altSettings()) {
                             for (USBEndpoint endpoint : ifaceDescriptor.endpoints()) {
                                 System.out.println(endpoint);
                             }
                         }
                     }
                     System.out.println("Requesting firmware version...");
                     byte[] data = new byte[1024];
                     int n = openDevice.sendControlTransfer(0xc0, (byte)'a', 0, 0, data);
                     System.out.println("Version: " + new String(data, 0, n, Charsets.US_ASCII));
                 }
             }
         }
     }
 }

该回答引用ChatGPT

如有疑问,可以回复我!

要实现这个功能,可以利用Java的库来监控USB设备的插入和移除,并记录文件的拷贝操作。以下是一些建议的步骤和可能用到的库:

1、监听USB设备插入和移除:
可以使用JNA(Java Native Access)库来访问操作系统本地功能。在Windows上,可以通过WM_DEVICECHANGE消息监听USB设备的插入和移除。首先,你需要添加JNA依赖项。如果你使用Maven,可以在pom.xml中添加以下依赖:



<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.10.0</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>5.10.0</version>
</dependency>

2、使用JNA,你可以创建一个继承自WindowProc的类来处理WM_DEVICECHANGE消息:


import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.WindowProc;

public class UsbDeviceListener implements WindowProc {
    @Override
    public LRESULT callback(HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam) {
        if (uMsg == WinUser.WM_DEVICECHANGE) {
            // 处理设备插入和移除的逻辑
        }
        return WinUser.DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

然后,在主类中注册该监听器:


import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.MSG;

public class Main {
    public static void main(String[] args) {
        UsbDeviceListener listener = new UsbDeviceListener();
        HWND hwnd = User32.INSTANCE.NewHWND(0);
        User32.INSTANCE.SetWindowLongPtr(hwnd, WinUser.GWL_WNDPROC, listener);

        MSG msg = new MSG();
        while (User32.INSTANCE.GetMessage(msg, hwnd, 0, 0)) {
            User32.INSTANCE.TranslateMessage(msg);
            User32.INSTANCE.DispatchMessage(msg);
        }
    }
}

获取USB设备信息:
可以使用javax.usb库来访问USB设备的信息。首先,在Maven的pom.xml中添加以下依赖:


<dependency>
    <groupId>javax.usb</groupId>
    <artifactId>javax-usb</artifactId>
    <version>1.0.2</version>
</dependency>

然后,在UsbDeviceListener类中,处理设备插入和移除的逻辑时,可以使用javax.usb库来获取设备的信息:



import javax.usb.*;
import java.util.List;

public class UsbDeviceListener implements WindowProc {
    // ...
    private void handleDevice

可以参考下面这篇文章
https://blog.csdn.net/l243225530/article/details/50034469

参考GPT和自己的思路,以下是通过Java监听USB移动介质的拔插和拷贝记录的示例代码:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.*;
import java.time.LocalDateTime;

public class USBListener {

    public static void main(String[] args) throws IOException, InterruptedException {
        // 监听的USB设备路径,Windows下通常为"E:\\"
        Path usbPath = Paths.get("E:\\");
        // 记录USB插拔和拷贝记录的文件路径
        File recordFile = new File("USBRecord.txt");

        // 监听器注册
        WatchService watchService = FileSystems.getDefault().newWatchService();
        WatchKey watchKey = usbPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);

        while (true) {
            // 等待事件发生
            watchKey = watchService.take();

            for (WatchEvent<?> event : watchKey.pollEvents()) {
                WatchEvent.Kind<?> kind = event.kind();
                // 判断事件类型
                if (kind == StandardWatchEventKinds.OVERFLOW) {
                    continue;
                } else if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                    // 记录拷贝记录
                    String fileName = event.context().toString();
                    String log = LocalDateTime.now() + " Created file " + fileName + " on " + usbPath;
                    writeLog(recordFile, log);
                } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
                    // 记录拔出记录
                    String fileName = event.context().toString();
                    String log = LocalDateTime.now() + " Deleted file " + fileName + " from " + usbPath;
                    writeLog(recordFile, log);
                } else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
                    // 记录修改记录
                    String fileName = event.context().toString();
                    String log = LocalDateTime.now() + " Modified file " + fileName + " on " + usbPath;
                    writeLog(recordFile, log);
                }
            }

            // 重置key
            boolean valid = watchKey.reset();
            if (!valid) {
                break;
            }
        }
    }

    private static void writeLog(File file, String log) throws IOException {
        FileWriter writer = new FileWriter(file, true);
        writer.write(log + "\n");
        writer.close();
    }
}

此代码使用Java的WatchService API实现对USB设备的监听,通过注册ENTRY_CREATE、ENTRY_DELETE、ENTRY_MODIFY事件,记录对USB设备中文件的操作记录,包括拷贝、拔出和修改等。该记录被写入指定的文件中,以便用户检查USB设备的使用历史。

引用最新版GPT4给予的意见和个人观点,有问题可以回复我哦

要实现监听USB移动介质的拔插和拷贝记录,可以使用Java中的JNotify库和Apache Commons IO库。

JNotify库可以用来监视文件系统事件,例如文件和目录的创建、修改和删除等。而Apache Commons IO库可以用来处理文件和目录的操作,例如复制、移动、删除等。

以下是大致的思路:

  1. 使用JNotify库监听USB移动介质的插入和拔出事件,并在事件触发时记录事件信息。例如,当USB移动介质插入时,记录插入的时间、设备名称、设备ID等信息;当USB移动介质拔出时,记录拔出的时间、设备名称、设备ID等信息。
  2. 在监听到USB移动介质插入事件时,使用Apache Commons IO库实现拷贝记录。具体地,可以遍历USB移动介质上的所有文件和目录,并将它们复制到指定的目录中。在复制过程中,记录每个文件的源路径和目标路径,以及复制的时间等信息。

以下是示例代码,可以帮助您实现这个功能:

javaCopy code
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyListener;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class UsbWatcher {
    private static final String USB_MOUNT_POINT = "/media/usb";
    private static final String COPY_TO_DIR = "/home/user/usb_copy";

    public static void main(String[] args) {
        int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
        boolean watchSubtree = true;

        try {
            int watchID = JNotify.addWatch(USB_MOUNT_POINT, mask, watchSubtree, new UsbListener());
            System.out.println("USB watcher started. Watch ID: " + watchID);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static class UsbListener implements JNotifyListener {
        @Override
        public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
            System.out.println("File renamed: " + oldName + " -> " + newName);
        }

        @Override
        public void fileModified(int wd, String rootPath, String name) {
            System.out.println("File modified: " + name);
        }

        @Override
        public void fileDeleted(int wd, String rootPath, String name) {
            System.out.println("File deleted: " + name);
        }

        @Override
        public void fileCreated(int wd, String rootPath, String name) {
            System.out.println("File created: " + name);

            if (rootPath.equals(USB_MOUNT_POINT)) {
                File sourceDir = new File(USB_MOUNT_POINT);
                File targetDir = new File(COPY_TO_DIR);
                try {
                    FileUtils.copyDirectory(sourceDir, targetDir);
                    System.out.println("USB content copied to: " + COPY_TO_DIR);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

这个示例代码使用JNotify库来监听USB移动介质上的文件系统事件,并在文件创建时使用Apache Commons IO库实现拷贝记录。

在这个示例代码中,我们定义了一个常量USB_MOUNT_POINT,它指定了USB移动介质的挂载点,以及一个常量COPY_TO_DIR,它指定了要将USB移动介质上的内容拷贝到哪个目录中。

然后我们使用JNotify库添加了一个监听器UsbListener,它实现了JNotifyListener接口中的四个方法:fileRenamedfileModifiedfileDeletedfileCreated。在这个示例代码中,我们只实现了fileCreated方法,当有文件被创建时,它会检查文件所在的路径是否为USB移动介质的挂载点,并使用Apache Commons IO库将USB移动介质上的内容复制到指定的目录中,并输出一条日志以记录复制的路径和时间。

请注意,这个示例代码中的JNotify库和Apache Commons IO库需要从它们的官方网站下载并导入到您的Java项目中。此外,您需要根据您的实际需要调整常量USB_MOUNT_POINTCOPY_TO_DIR的值。

最后,需要注意的是,这个示例代码只能在Linux或类Unix系统上运行。如果您的系统是Windows或其他操作系统,您需要根据不同的操作系统调整文件路径、文件系统事件的参数等。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
实现通过Java监听 USB 移动介质的拔插和拷贝记录,可以通过使用 Java 提供的 JNA(Java Native Access)库调用 Windows 提供的 API 来实现。下面是具体步骤:

  1. 引入 JNA 库
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.9.0</version>
</dependency>
  1. 定义回调函数

定义回调函数处理 USB 设备的插入、弹出事件,该回调函数会在 Windows 系统内核发送通知时被调用。

public interface WinUser extends StdCallLibrary {
    // 回调函数
    public interface WNDPROC extends StdCallCallback {
        LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
    }

    // 注册设备插入弹出通知
    HWND HWND_BROADCAST = new HWND(Pointer.createConstant(-1));
    int WM_DEVICECHANGE = 0x0219;
    int DBT_DEVICEARRIVAL = 0x8000;
    int DBT_DEVICEREMOVECOMPLETE = 0x8004;

    HMODULE GetModuleHandle(final String name);
    HWND SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hInstance, int threadId);
    LRESULT CallNextHookEx(int idHook, int nCode, WPARAM wParam, LPARAM lParam);
    HWND FindWindow(final String lpClassName, final String lpWindowName);

    public static final int WH_CALLWNDPROC = 4;

    public static final int HC_ACTION = 0;
}
  1. 检测 USB 设备的插入和弹出事件

使用 JNA 调用 WinUser 库提供的函数,使用回调函数处理USB设备的插入和弹出。

public class USBMonitor {

    private static final WinUser.WNDPROC messageHandler = new WinUser.WNDPROC() {
        @Override
        public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam) {
            if (uMsg == WinUser.WM_DEVICECHANGE) {
                WinUser.DEV_BROADCAST_HDR hdr = new WinUser.DEV_BROADCAST_HDR(new Pointer(lParam.longValue()));
                switch (uParam.intValue()) {
                    case WinUser.DBT_DEVICEARRIVAL:
                        if (hdr.dbch_devicetype == WinUser.DBT_DEVTYP_VOLUME) {
                            WinUser.DEV_BROADCAST_VOLUME vol = new WinUser.DEV_BROADCAST_VOLUME(new Pointer(lParam.longValue()));
                            String driveLetter = getDriveLetter(vol.dbcv_unitmask);
                            System.out.println(String.format("%s inserted", driveLetter));
                        }
                        break;
                    case WinUser.DBT_DEVICEREMOVECOMPLETE:
                        if (hdr.dbch_devicetype == WinUser.DBT_DEVTYP_VOLUME) {
                            WinUser.DEV_BROADCAST_VOLUME vol = new WinUser.DEV_BROADCAST_VOLUME(new Pointer(lParam.longValue()));
                            String driveLetter = getDriveLetter(vol.dbcv_unitmask);
                            System.out.println(String.format("%s removed", driveLetter));
                        }
                        break;
                    default:
                        break;
                }
            }
            return User32.INSTANCE.CallNextHookEx(null, uMsg, uParam, lParam);
        }
    };

    private static String getDriveLetter(long unitmask) {
        String[] letters = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P"};
        int offset = 0;
        while ((unitmask >>= 1) != 0) {
            offset++;
        }
        return letters[offset];
    }

    public static void main(String[] args) {
        WinUser lib = Native.loadLibrary("user32", WinUser.class);
        WinUser.HHOOK hhk = lib.SetWindowsHookEx(WinUser.WH_CALLWNDPROC, (WinUser.HOOKPROC) messageHandler,
                lib.GetModuleHandle(null), 0);

        WinUser.MSG msg = new WinUser.MSG();
        while (true) {
            if (lib.GetMessage(msg, null, 0, 0) == -1) {
                break;
            } else {
                lib.TranslateMessage(msg);
                lib.DispatchMessage(msg);
            }
        }
        lib.UnhookWindowsHookEx(hhk);
    }
}

运行程序时会输出 USB 设备的插入和弹出信息。

如果需要实现监听拷贝事件的功能,可以使用Java的NIO(New I/O)库,使用WatchService API实现对USB设备的监听。

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class USBFileMonitor {

    public static void main(String[] args) throws IOException, InterruptedException {

        // 选取要监视的 USB 设备的根路径
        Path usbRootPath = Paths.get("F:/");

        // 创建 WatchService 对象,监视 USB 设备
        try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
            usbRootPath.register(watchService,
                    StandardWatchEventKinds.ENTRY_CREATE,
                    StandardWatchEventKinds.ENTRY_MODIFY,
                    StandardWatchEventKinds.ENTRY_DELETE);

            while (true) {
                WatchKey key = watchService.take();

                for (WatchEvent<?> event : key.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();

                    // 只监视拷贝事件
                    if (kind == StandardWatchEventKinds.ENTRY_CREATE ||
                        kind == StandardWatchEventKinds.ENTRY_MODIFY) {
                        Path filename = (Path) event.context();
                        System.out.println("文件拷贝:" + usbRootPath.resolve(filename));
                    }
                }

                // 重置 WatchKey
                boolean valid = key.reset();
                if (!valid) {
                    break;
                }
            }
        }
    }
}

参考资料:

  1. https://stackoverflow.com/questions/8296399/detecting-programs-that-write-to-the-file-system
  2. https://stackoverflow.com/questions/7987664/how-to-get-a-windows-drive-letter-from-a-device-path-with-java
  3. http://www.nakov.com/blog/2009/07/28/usb-drive-detection-in-java-part-1/
  4. http://www.nakov.com/blog/2009/07/28/usb-drive-detection-in-java-part-2/
    如果我的回答解决了您的问题,请采纳!

实现通过Java监听USB移动介质的拔插和拷贝记录,可以使用Java提供的JNA(Java Native Access)库来访问操作系统底层的API,从而实现对USB设备的监听和操作。

具体实现思路如下:

使用JNA库调用Windows API或Linux API获取USB设备的信息,识别出插入或拔出的USB存储设备。

使用JNA库读取或写入USB存储设备中的文件,在文件被复制到电脑本地磁盘时记录相关的信息,例如文件路径、文件名、大小等等。

使用数据库或者日志记录工具将记录的信息保存下来,便于后续查询和分析。

需要注意的是,针对不同的操作系统,需要使用不同的API来实现对USB设备的监听和操作。在Windows平台上,可以使用Win32 API中的DeviceIoControl函数和RegisterDeviceNotification函数实现对USB设备的监听,而在Linux平台上则可以使用udev和HAL等库来实现类似的功能。

在实际开发过程中,还需要考虑一些其他的问题,例如多线程并发访问、异常处理等等。因此,建议您找一个在这方面有经验的开发人员进行协助。

您可以使用Java的JNA库来实现监听USB移动介质的拔插和拷贝记录。JNA是一种Java本地接口技术,可以用于调用本地C/C++库中的函数和数据结构。

具体来说,您可以使用JNA来调用Windows API中的RegisterDeviceNotification函数和ReadDirectoryChangesW函数。RegisterDeviceNotification函数可以用于注册USB设备的插拔事件,ReadDirectoryChangesW函数可以用于监视文件夹中文件的创建、修改和删除等事件。

以下是示例代码:

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase.FILE_NOTIFY_INFORMATION;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
import com.sun.jna.platform.win32.WinNT.PVOID;
import com.sun.jna.platform.win32.WinNT.WCHAR;
import com.sun.jna.ptr.IntByReference;

public class USBMonitor {
    private static final int BUFFER_SIZE = 1024;
    private static final int FILE_NOTIFY_CHANGE_FILE_NAME = 0x00000001;
    private static final int FILE_NOTIFY_CHANGE_DIR_NAME = 0x00000002;
    private static final int FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x00000004;
    private static final int FILE_NOTIFY_CHANGE_SIZE = 0x00000008;
    private static final int FILE_NOTIFY_CHANGE_LAST_WRITE = 0x00000010;
    private static final int FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x00000020;
    private static final int FILE_NOTIFY_CHANGE_CREATION = 0x00000040;
    private static final int FILE_NOTIFY_CHANGE_SECURITY = 0x00000100;

    public static void main(String[] args) {
        // 注册USB设备的插拔事件
        HANDLE hDevNotify = registerDeviceNotification();
        if (hDevNotify == null) {
            System.err.println("Failed to register device notification");
            return;
        }

        // 监视文件夹中文件的创建、修改和删除等事件
        HANDLE hDir   = Kernel32.INSTANCE.CreateFile(
            "C:\\USB", 
            Kernel32.FILE_LIST_DIRECTORY, 
            Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE | Kernel32.FILE_SHARE_DELETE, 
            null, 
            Kernel32.OPEN_EXISTING, 
            Kernel32.FILE_FLAG_BACKUP_SEMANTICS | Kernel32.FILE_FLAG_OVERLAPPED, 
            null);
        if (hDir == null) {
            System.err.println("Failed to open directory");
            return;
        }

        // 创建异步I/O操作
        byte[] buffer = new byte[BUFFER_SIZE];
        Pointer p = new Memory(buffer.length);
        IntByReference lpBytesReturned = new IntByReference();
        OVERLAPPED overlapped = new OVERLAPPED();
        overlapped.hEvent = Kernel32.INSTANCE.CreateEvent(null, true, false, null);

        // 监听USB设备的插拔事件和文件夹中文件的创建、修改和删除等事件
        while (true) {
            // 监听USB设备的插拔事件
            DWORD dwBytesReturned = new DWORD();
            HANDLEByReference phDevNotify = new HANDLEByReference(hDevNotify);
            if (!Kernel32.INSTANCE.GetOverlappedResult(hDevNotify, overlapped, dwBytesReturned, true)) {
                System.err.println("Failed to get overlapped result");
                break;
            }

            // 监听文件夹中文件的创建、修改和删除等事件
            if (Kernel32.INSTANCE.ReadDirectoryChangesW(
                hDir, 
                p, 
                buffer.length, 
                true, 
                FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SECURITY, 
                lpBytesReturned, 
                overlapped, 
                null)) {
                FILE_NOTIFY_INFORMATION fni = new FILE_NOTIFY_INFORMATION(p);
                while (fni != null) {
                    System.out.println(fni.getFileName());
                    fni = FILE_NOTIFY_INFORMATION.next(fni);
                }
            } else {
                System.err.println("Failed to read directory changes");
                break;
            }
        }

        // 关闭USB设备的插拔事件和文件夹的句柄
        Kernel32.INSTANCE.Close

以上是示例代码,您可以根据具体需求进行相应的调整和优化。需要注意的是,JNA调用本地函数的过程比较复杂,需要仔细学习和理解。在实际应用中,您需要根据具体情况进行相应的调整和优化。

参考于:Cursor 应用

要实现通过 Java 监听 USB 移动介质的拔插和拷贝记录,可以使用 Java 的 javax.usb 和 javax.imageio 等 API。具体的实现步骤如下:

1.导入依赖库

要使用 javax.usb API,需要导入对应的依赖库。可以从如下网址下载:

usb4java: http://usb4java.org/
2.检测USB设备插入和拔出事件

使用 javax.usb API 来检测 USB 设备的插入和拔出事件。可以使用如下代码:

import javax.usb.*;
import javax.usb.event.*;

public class USBListener implements UsbDeviceListener {

    @Override
    public void usbDeviceAttached(UsbDeviceEvent event) {
        UsbDevice device = event.getUsbDevice();
        // TODO: 处理 USB 设备插入事件
    }

    @Override
    public void usbDeviceDetached(UsbDeviceEvent event) {
        UsbDevice device = event.getUsbDevice();
        // TODO: 处理 USB 设备拔出事件
    }
}


然后,通过如下代码注册 USB 设备监听器:

UsbServices services = UsbHostManager.getUsbServices();
UsbDevice device = services.getRootUsbHub();
device.addUsbDeviceListener(new USBListener());


3.检测文件拷贝事件

使用 Java 的 javax.imageio API 来检测文件拷贝事件。可以使用如下代码:

import javax.imageio.*;
import javax.imageio.event.*;
import java.io.*;

public class FileListener implements IIOReadProgressListener, IIOWriteProgressListener {

    @Override
    public void imageStarted(ImageReader source, int imageIndex) {
        // TODO: 处理文件读取开始事件
    }

    @Override
    public void imageComplete(ImageReader source) {
        // TODO: 处理文件读取结束事件
    }

    @Override
    public void imageProgress(ImageReader source, float percentageDone) {
        // TODO: 处理文件读取进度事件
    }

    @Override
    public void imageStarted(ImageWriter source, int imageIndex) {
        // TODO: 处理文件写入开始事件
    }

    @Override
    public void imageComplete(ImageWriter source) {
        // TODO: 处理文件写入结束事件
    }

    @Override
    public void imageProgress(ImageWriter source, float percentageDone) {
        // TODO: 处理文件写入进度事件
    }
}


然后,通过如下代码注册文件监听器:

ImageIO.addIIOReadProgressListener(new FileListener());
ImageIO.addIIOWriteProgressListener(new FileListener());


在处理文件读取开始和结束事件时,可以记录下拷贝的文件路径。需要注意的是,文件读取事件可能会发生多次,需要在事件处理时进行相应的处理。

题主,这个问题我来替你解决,若有帮助,还望采纳,点击回答右侧采纳即可。

思路一.在WinFrom中通过拦截Windows 消息机制来实现. 类似定义MEssageForm窗体. 假如用鼠标左击一下窗体, 系统会收到一条 WM_LBUTTONDOWN 消息;当鼠标抬起, 系统又会收到 WM_LBUTTONUP 消息.系统收到消息后, 会告诉窗体发生的事情, 然后窗体再做出反应; 当然窗体能否做出反应要看窗体是否有相应的响应代码. 同样也可以把USB设备插拔事件通过重写窗体WndProc(Ref Message m)方法拦截并处理.

首先引入命名空间:

1:using System.Management;

2:using System.Threading;

3:using System.Security.Permissions;

定义Device Management Event的枚举:

1: public enum DeviceEvent : int

2: {

3: DBT_CONFIGCHANGECANCELED = 0x0019,

4: DBT_CONFIGCHANGED=0x0018,

5: DBT_CUSTOMEVENT=0x8006,

6: DBT_DEVICEARRIVAL=0x8000,//USB Insert DEvice Statu

7: DBT_DEVICEQUERYREMOVE=0x8001,

8: DBT_DEVICEQUERYREMOVEFAILED=0x8002,

9: DBT_DEVICEREMOVEPENDING=0x8003,//USB Revoing.

10: DBT_DEVICEREMOVECOMPLETE=0x8004,//USB Remove Completed

11: DBT_DEVICETYPESPECIFIC=0x8005,

12: DBT_DEVNODES_CHANGED=0x0007,//Device List _Changed

13: DBT_QUERYCHANGECONFIG=0x0017,

14: DBT_USERDEFINED=0xFFFF

15: }

其中涉及到USB设备插拔的是DEVICEREMOVEPENDING/DEVICEREMOVECOMPLETE[删除] DEVICEARRIVAL[插入设备] 重写WinFProc实现窗体上对Windows MEssage进行拦截并重新处理:

1: [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]

2: protected override void WndProc(ref Message m)

3: {

4: base.WndProc(ref m);

5: DeviceEvent lEvent;

6:

7: lEvent = (DeviceEvent)m.WParam.ToInt32();

8: switch (lEvent)

9: {

10: case DeviceEvent.DBT_DEVICEARRIVAL://[Insert]

11: this.CheckDeviceStatus_Lable.BackColor = Color.Green;

12: this.CheckDeviceStatus_Lable.Text = "----Connection Device!----";

13: MessageBox.Show("Just Insert At Moment !", "Insert");

14: break;

15: case DeviceEvent.DBT_DEVICEREMOVECOMPLETE://[REmove]

16: this.CheckDeviceStatus_Lable.BackColor = Color.Red;

17: this.CheckDeviceStatus_Lable.Text = "------No Connection------";

18: MessageBox.Show("Remove Complete At Moment!", "Remove");

19: break;

20: case DeviceEvent.DBT_DEVNODES_CHANGED://[Device List Have Changed]

21: MessageBox.Show("Device List have been Changed!");

22: break;

23: default:

24: break;

25: }

26: }