最近项目需要 做一个在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管理拷贝、容量校验、容错
MainWindowUI 展示与用户交互

// 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

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐