目录
- 方法一:Liunx
- 11usb.cpp
- 效果
- 方法二:Liunx+QT
- udisk.cpp
- udisk.h
- ui
- 结构
- 效果
- 文件
- 参考
- 改进参考
注意:本人U盘已经使用
sudo mkfs.ntfs /dev/sdb1
U盘分区格式化
方法一:Liunx
- 检测U盘是否存在
- 检测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,把显示结果赋给resvecif (resvec.size() == 0)// 执行df_path,没有结果,需要手动挂载{printf("no USB------df -h|grep /dev/------%d\n", __LINE__);// 手动挂载,创建挂载目录usbsystem("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
- 检测U盘是否存在
- 检测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,把显示结果赋给resvecif (resvec.size() == 0)// 执行df_path,没有结果,需要手动挂载{ui->textBrowser->append(QString(df_path)+"没有结果,需要手动挂载");ui->textBrowser->append("手动挂载");// 手动挂载,创建挂载目录usbsystem("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_NAMESPACEclass Udisk : public QWidget
{Q_OBJECTpublic: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)