Qt 在linux 平台下检测 是否插入U盘,拷贝文件,显示盘符(用的是Linux底层函数 可以移植到非qt的项目)
最近项目需要 做一个在qt平台下的
1)检测是否插入U盘
2)扫描本地硬盘的文件并,拷贝文件到U盘
3)并能容错处理例如 可以判断U盘容量,拷贝过程中U盘拔出,提示容错
✅ 1. 检测是否插入 U 盘
-
使用
QStorageInfo监控存储设备:
#include <QStorageInfo> QList<QStorageInfo> drives = QStorageInfo::mountedVolumes(); for (const QStorageInfo &drive : drives) { if (drive.isValid() && drive.isReady() && drive.isRemovable()) { qDebug() << "U盘已插入: " << drive.rootPath(); } }
-
可使用
QTimer每秒定时轮询,也可以用 udev(Linux)或QFileSystemWatcher监听/media或/run/media路径变化。
✅ 2. 扫描本地硬盘并拷贝文件到 U 盘
-
使用
QDirIterator遍历硬盘文件:
#include <QDirIterator> QStringList filesToCopy; QDirIterator it("/home/user/data", QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { filesToCopy << it.next(); }
-
拷贝文件时,使用
QFile::copy()并判断目标路径是否在 U 盘挂载点(如/media/usb)下。
✅ 3. 容错处理
✔ 判断 U 盘容量
QStorageInfo usb("/media/usb"); // U 盘挂载路径 qint64 bytesAvailable = usb.bytesAvailable(); qint64 fileSize = QFileInfo(filePath).size(); if (bytesAvailable < fileSize) { QMessageBox::warning(nullptr, "空间不足", "U 盘空间不足,无法拷贝文件"); return; }
✔ 判断 U 盘是否已移除
-
在每次
copy前后检查QStorageInfo::isReady()。 -
若拷贝失败,可捕获
QFile::copy()返回值或使用QFile::open()的错误码处理。
if (!usbInfo.isReady()) { QMessageBox::critical(nullptr, "U盘已拔出", "U盘已移除,拷贝中止"); return; }
-
检测 U 盘插入/拔出(使用
QStorageInfo和定时器); -
扫描指定路径的本地硬盘文件(使用
QDirIterator); -
拷贝文件到 U 盘,并进行如下容错:
-
判断 U 盘容量是否足够;
-
拷贝中检测 U 盘是否被拔出;
-
提示用户错误或完成状态。
-
示例架构模块划分建议
| 模块 | 作用 |
|---|---|
UsbMonitor | 检测并识别 U 盘插拔 |
FileScanner | 扫描本地指定目录文件 |
CopyManager | 管理拷贝、容量校验、容错 |
MainWindow | UI 展示与用户交互 |
// Qt 工程结构示例:U盘检测 + 文件扫描 + 容错拷贝
// 1. main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
// 2. mainwindow.h
#pragma once
#include <QMainWindow>
#include <QStorageInfo>
#include <QTimer>
#include <QFile>
#include <QDirIterator>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void checkUsb();
void startCopy();
private:
Ui::MainWindow *ui;
QTimer *usbCheckTimer;
QString usbPath;
bool isUsbMounted;
QStringList scanFiles(const QString &dirPath);
bool copyFileWithCheck(const QString &srcPath, const QString &destDir);
};
// 3. mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow), isUsbMounted(false) {
ui->setupUi(this);
usbCheckTimer = new QTimer(this);
connect(usbCheckTimer, &QTimer::timeout, this, &MainWindow::checkUsb);
usbCheckTimer->start(2000);
connect(ui->copyButton, &QPushButton::clicked, this, &MainWindow::startCopy);
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::checkUsb() {
foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) {
if (storage.isValid() && storage.isReady() && storage.isRemovable()) {
usbPath = storage.rootPath();
if (!isUsbMounted) {
isUsbMounted = true;
ui->statusbar->showMessage("U盘已插入: " + usbPath);
}
return;
}
}
if (isUsbMounted) {
isUsbMounted = false;
ui->statusbar->showMessage("U盘已拔出");
}
}
QStringList MainWindow::scanFiles(const QString &dirPath) {
QStringList files;
QDirIterator it(dirPath, QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
files << it.next();
}
return files;
}
bool MainWindow::copyFileWithCheck(const QString &srcPath, const QString &destDir) {
QStorageInfo usbInfo(usbPath);
QFileInfo fi(srcPath);
if (usbInfo.bytesAvailable() < fi.size()) {
QMessageBox::warning(this, "空间不足", "U盘空间不足,无法拷贝: " + fi.fileName());
return false;
}
if (!usbInfo.isReady()) {
QMessageBox::critical(this, "U盘错误", "U盘已移除,拷贝中止。");
return false;
}
QString destPath = destDir + "/" + fi.fileName();
return QFile::copy(srcPath, destPath);
}
void MainWindow::startCopy() {
if (!isUsbMounted) {
QMessageBox::warning(this, "未检测到U盘", "请插入U盘后重试。");
return;
}
QStringList files = scanFiles("/home/user/testdata"); // 替换为你的硬盘扫描目录
foreach (const QString &file, files) {
if (!copyFileWithCheck(file, usbPath)) {
break;
}
}
QMessageBox::information(this, "完成", "文件拷贝完成。\n目标路径: " + usbPath);
}
// 4. mainwindow.ui (Qt Designer 中添加):
// - QLabel statusbar
// - QPushButton 复制按钮,objectName 设置为 "copyButton"
// - 可添加 QTextBrowser 用于显示日志
// 🔧 工程配置(.pro)示例:
// QT += core gui widgets
// HEADERS += mainwindow.h
// SOURCES += main.cpp mainwindow.cpp
// FORMS += mainwindow.ui
更多推荐
所有评论(0)