1.使用到libudev库,没有可使用命令安装:
sudo apt-get install libudev-dev
2.在.pro文件增加对libudev库的链接
LIBS += -ludev
3.头文件.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private:
struct udev *udevs;
struct udev_monitor *monitor;
private:
void uDiskDriveEvent();
QString getUsbDiskMountPoint(const QString &usbDiskPath);
QString getUsbDiskMountPoint2();
QString searchFileInUsbDisk(const QString &usbDiskPath, const QString &fileName);
};
#endif // MAINWINDOW_H
4.源文件.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <libudev.h>
#include <QSocketNotifier>
#include <QDebug>
#include <QProcess>
#include <QStorageInfo>
#include <QDirIterator>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
udevs = udev_new();
if (!udevs) //U盘初始化失败
{
return;
}
monitor = udev_monitor_new_from_netlink(udevs, "udev"); //创建一个udev对象来监听设备事件
udev_monitor_filter_add_match_subsystem_devtype(monitor, "block", NULL); //指定设备子系统
udev_monitor_enable_receiving(monitor); //将监视器添加到事件循环中
int fd = udev_monitor_get_fd(monitor);
QSocketNotifier *notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
connect(notifier, &QSocketNotifier::activated, this, &MainWindow::uDiskDriveEvent);
}
MainWindow::~MainWindow()
{
delete ui;
// 释放udev和udev_monitor结构体指针
udev_monitor_unref(monitor);
udev_unref(udevs);
}
//u盘插入处理函数
void MainWindow::uDiskDriveEvent()
{
struct udev_device *dev = udev_monitor_receive_device(monitor);
if (dev)
{
const char *action = udev_device_get_action(dev);
if (action && (0 == strcmp(action, "add"))) //插入u盘
{
qDebug() << "插入u盘";
const char *devpath = udev_device_get_devpath(dev);
const char *devname = udev_device_get_devnode(dev);
qDebug() << "u盘路径:" << devpath << "节点名称:" << devname;
QString mountPoint = getUsbDiskMountPoint(devname);
// 在u盘中寻找target.txt
QString targetFile = searchFileInUsbDisk(mountPoint, "target.txt");
if (!targetFile.isEmpty()) {
qDebug() << "目标文件路径: " << targetFile;
// 此处可以写对target.txt的处理
} else {
qDebug() << "未找到文件";
}
}
else if(action && (0 == strcmp(action, "remove"))) //拔出u盘
{
qDebug() << "拔出u盘";
}
udev_device_unref(dev); //释放udev_device对象的引用
}
}
//获取挂载路径函数
QString MainWindow::getUsbDiskMountPoint(const QString &usbDiskPath)
{
// 相当于在命令行输入mount命令获取u盘挂载路径
QProcess process;
process.start("mount");
process.waitForFinished(-1);
QByteArray output = process.readAllStandardOutput();
QString mountOutput = QString::fromUtf8(output);
// 读取mount on 后的字段,也就是挂载路径的文本
QString searchString = usbDiskPath + " on "; //相当于找这段文本/dev/sda1 on /mnt/sda1
int index = mountOutput.indexOf(searchString);
if (index != -1) {
// 如果找到把on后面的文本/mnt/sda1提取出来
QString mountPath = mountOutput.mid(index + searchString.length());
mountPath = mountPath.left(mountPath.indexOf(' '));
qDebug() << "挂载路径:" << mountPath;
return mountPath;
} else {
qDebug() << "未找到路径";
return QString();
}
}
//获取挂载路径函数
QString MainWindow::getUsbDiskMountPoint2()
{
QString mountPath;
foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes())
{
if (storage.isValid() && storage.isReady())
{
if (storage.rootPath().contains("sd")) {
mountPath = storage.rootPath();
qDebug() << "挂载路径:" << mountPath;
return mountPath;
}
else {
qDebug() << "未找到路径";
return QString();
}
} else {
qDebug() << "未找到路径";
return QString();
}
}
}
//查找特定文件函数
QString MainWindow::searchFileInUsbDisk(const QString &usbDiskPath, const QString &fileName)
{
//使用QT遍历器,遍历读取u盘中的所有文件
QDirIterator it(usbDiskPath, QDir::Files | QDir::NoSymLinks, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString filePath = it.next();
QFileInfo fileInfo(filePath);
if (fileInfo.fileName() == fileName) {
return fileInfo.filePath(); //找到返回文件路径
}
}
return QString(); // 文件未找到
}