U盘检测-linux+QT

注意:本人U盘已经使用​ sudo mkfs.ntfs /dev/sdb1 U盘分区格式化

方法一:Liunx

  1. 检测U盘是否存在
  2. 检测U盘自动挂载还是需要手动挂载

11usb.cpp

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
//执行一个shell命令,输出结果逐行存储在resvec中,并返回行数
int32_t myexec(const char *cmd, vector<string> &resvec)
{
    resvec.clear();
    FILE *pp = popen(cmd, "r"); //建立管道
    if (!pp)
    {
        return -1;
    }
    char tmp[1024]; //设置一个合适的长度,以存储每一行输出
    while (fgets(tmp, sizeof(tmp), pp) != NULL)
    {
        if (tmp[strlen(tmp) - 1] == '\n')
        {
            tmp[strlen(tmp) - 1] = '\0'; //去除换行符
        }
        resvec.push_back(tmp);
    }
    pclose(pp); //关闭管道
    for (int i = 0; i < resvec.size(); i++)
    {
        cout << resvec.at(i) << endl;
        cout << "-----------------------------" << endl;
    }
    return resvec.size();
}
int main(int argc, char const *argv[])
{
    printf("%s------------%d\n", __FUNCTION__, __LINE__);
    // 1.判断U盘是否存在
    DIR *dir_ptr;
    int usb_bool = 0;
    struct dirent *direntp;
    if ((dir_ptr = opendir("/proc/scsi/usb-storage")) == NULL)
    {
        printf("down=0 %p \n", dir_ptr);
        usb_bool = 0; //拔下来的时候一定要清0
    }
    else //存储设备是插上了
    {
        usb_bool = 1;
        printf("up=1  %p \n", dir_ptr);

        // 2.找出sd**
        for (int i = 0; i < 6; i++)
        {
            const char *sdx[] = {"sda", "sdb", "sdc", "sdd", "sde", "sdf"};
            char open_path[64] = {0};
            sprintf(open_path, "/sys/block/%s/removable", sdx[i]);
            printf("open_path==[%s]\n", open_path);

            // 3.判断磁盘是否属于U盘
            int fd = open(open_path, O_RDONLY);
            if (fd == -1)
            {
                printf("open error------------%d\n", __LINE__);// 打开失败
            }
            else
            {
                char buf[32] = {0};
                if (read(fd, buf, sizeof(buf)) > 0)//读
                {

                    printf("buf==[%s]-strlen(buf)=%d\n", buf, (int)strlen(buf));
                    printf("buf==[%c]\n", buf[0]);
                    if (buf[0] == '1')//属于U盘
                    {
                        printf("is USB------------%d\n", __LINE__);
                        // 如果已经自动挂载,找到目录,拷贝就行
                        vector<string> resvec;
                        char df_path[64] = {0};
                        sprintf(df_path,"df -h|grep /dev/%s", sdx[i]);
                        myexec(df_path, resvec);//执行df_path,把显示结果赋给resvec
                        if (resvec.size() == 0)// 执行df_path,没有结果,需要手动挂载
                        {
                            printf("no USB------df -h|grep /dev/------%d\n", __LINE__);
                            // 手动挂载,创建挂载目录usb
	                        system("mkdir -p /mnt/usb"); // -p目录早已存在则不当作错误
	                        
	                        system("mount -t ntfs /dev/sdb1 /mnt/usb/");//挂载
	                        
	                        system("cp /mnt/hgfs/share-2/demo/11usb.cpp /mnt/usb/");
	                        
	                        system("umount /mnt/usb/");// 取消挂载
	                        break;
                        }
                        else
                        {
                            cout << resvec.back() << endl;
                            char *str = (char *)resvec.back().c_str();
                            const char s[2] = " ";
                            char path[128] = {0};
                            char *token;
                            token = strtok(str, " "); //获取第一个子字符串
                            while (token != NULL)
                            { //继续获取其他的子字符串
                                printf("%s\n", token);
                                strcpy(path, token);
                                token = strtok(NULL, s);
                            }
                            printf("path==[%s]\n", path);
                            int ret = system("cp /mnt/hgfs/share-2/demo/11usb.cpp /mnt/usb/");
                            printf("is USB--ret==%d----------%d\n", ret, __LINE__);
                            break;
                        }        
                    }
                    else
                    {
                        printf("no USB------------%d\n", __LINE__);
                    }
                }
            }
            close(fd);
        }
        closedir(dir_ptr);
    }
    return 0;
}

效果

  • df -h

在这里插入图片描述

  • 执行程序
  • 没有插U盘
    在这里插入图片描述
  • 插U盘
  • sdb是U盘(图片注释打错了)

在这里插入图片描述

方法二:Liunx+QT

  1. 检测U盘是否存在
  2. 检测U盘自动挂载还是需要手动挂载

udisk.cpp

建议使用QFile QString QVector ,由于时间成本因素,还是沿用上面的代码

#include "udisk.h"
#include "ui_udisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
#include <string.h>
#include <vector>
Udisk::Udisk(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Udisk)
{
    ui->setupUi(this);
    this->setWindowTitle("U盘检测");
}

Udisk::~Udisk()
{
    delete ui;
}

int32_t Udisk::myexec(const char *cmd, std::vector<std::string> &resvec)
{
    resvec.clear();
    FILE *pp = popen(cmd, "r"); //建立管道
    if (!pp)
    {
        return -1;
    }
    char tmp[1024]; //设置一个合适的长度,以存储每一行输出
    while (fgets(tmp, sizeof(tmp), pp) != NULL)
    {
        if (tmp[strlen(tmp) - 1] == '\n')
        {
            tmp[strlen(tmp) - 1] = '\0'; //去除换行符
        }
        resvec.push_back(tmp);
    }
    pclose(pp); //关闭管道
    for (int i = 0; i<(int)resvec.size(); i++)
    {
        ui->textBrowser->append(QString(resvec.at(i).c_str()));
    }
    return resvec.size();
}

void Udisk::on_checkBtn_clicked()
{
    ui->textBrowser->clear();
    // 1.判断U盘是否存在
    DIR *dir_ptr;
    int usb_bool = 0;
    if ((dir_ptr = opendir("/proc/scsi/usb-storage")) == NULL)
    {
        ui->textBrowser->append("U盘不存在");
        usb_bool = 0; //拔下来的时候一定要清0
    }
    else //存储设备是插上了
    {
        usb_bool = 1;
        ui->textBrowser->append("U盘存在");

        // 2.找出sd**
        for (int i = 0; i < 6; i++)
        {
            const char *sdx[] = {"sda", "sdb", "sdc", "sdd", "sde", "sdf"};
            char open_path[64] = {0};
            sprintf(open_path, "/sys/block/%s/removable", sdx[i]);

            // 3.判断磁盘是否属于U盘
            int fd = open(open_path, O_RDONLY);
            if (fd == -1)
            {
                ui->textBrowser->append("打开失败:"+QString(open_path));
            }
            else
            {
                char buf[32] = {0};
                if (read(fd, buf, sizeof(buf)) > 0)//读
                {
                    ui->textBrowser->append("读取:"+QString(open_path)+"  ["+QString(buf[0])+"]");
                    if (buf[0] == '1')//属于U盘
                    {
                        ui->textBrowser->append("["+QString(sdx[i])+"]是U盘");
                        // 如果已经自动挂载,找到目录,拷贝就行
                        char cmd[32]={0};
                        std::vector<std::string> resvec;
                        char df_path[64] = {0};
                        sprintf(df_path,"df -h|grep /dev/%s", sdx[i]);
                        myexec(df_path, resvec);//执行df_path,把显示结果赋给resvec
                        if (resvec.size() == 0)// 执行df_path,没有结果,需要手动挂载
                        {
                            ui->textBrowser->append(QString(df_path)+"没有结果,需要手动挂载");
                            ui->textBrowser->append("手动挂载");
	                        // 手动挂载,创建挂载目录usb
	                        system("mkdir -p /mnt/usb"); // -p目录早已存在则不当作错误
	
	                        sprintf(cmd,"mount -t ntfs /dev/%s1 /mnt/usb/", sdx[i]);
                            system(cmd);//挂载
                            	
	                        //system("cp /mnt/hgfs/share-2/demo/11usb.cpp /mnt/usb/");
	
	                        system("umount /mnt/usb/");// 取消挂载
	                        break;
                        }
                        else
                        {
                            ui->textBrowser->append("自动挂载:"+QString(resvec.back().c_str()));
                            char *str = (char *)resvec.back().c_str();
                            const char s[2] = " ";
                            char path[128] = {0};
                            char *token;
                            token = strtok(str, " "); //获取第一个子字符串
                            while (token != NULL)
                            { //继续获取其他的子字符串
                                strcpy(path, token);
                                token = strtok(NULL, s);
                            }
                            ui->textBrowser->append("挂载路径["+QString(path)+"]");
                            //system("cp /mnt/hgfs/share-2/demo/11usb.cpp /mnt/usb/");
                            break;
                        }
                    }
                    else
                    {
                        ui->textBrowser->append("["+QString(sdx[i])+"]不是U盘");
                    }
                }
            }
           // QWidget::close()与stdio.h中的文件关闭标准函数close()产生了歧义
           // 区分成员函数与全局函数,就要在全局函数前面增加"::"双冒号的标志
           ::close(fd);
        }
        closedir(dir_ptr);
    }
}

udisk.h

#ifndef UDISK_H
#define UDISK_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Udisk; }
QT_END_NAMESPACE

class Udisk : public QWidget
{
    Q_OBJECT

public:
    Udisk(QWidget *parent = nullptr);
    ~Udisk();
    //执行一个shell命令,输出结果逐行存储在resvec中,并返回行数
    int32_t myexec(const char *cmd, std::vector<std::string> &resvec);

private slots:
    void on_checkBtn_clicked();// 使用ui设计器的转到槽

private:
    Ui::Udisk *ui;
};
#endif // UDISK_H

ui

在这里插入图片描述

结构

在这里插入图片描述

效果

  • df -h
    在这里插入图片描述

  • 执行程序

  • 没有插U盘
    在这里插入图片描述

  • 插U盘
    在这里插入图片描述

文件

有道云:U盘检测源码

参考

根目录定义|硬件设备在linux下的命名

利用/proc/scsi/usb-storage来判断 U盘的移入/移出

判断磁盘是否属于U盘

获取U盘挂载路径

C++ strtok函数详解|字符串分割

挂载U盘

改进参考

Linux下如何用QT检测到U盘已经插入

Linux c检测USB热插拔(netlink)

  • 1
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值