当前位置: 首页 > news >正文

Qt案例 以单线程或者单生产者多消费者设计模式实现QFTP模块上传文件夹功能

前文:Qt案例 使用QFtpServerLib开源库实现Qt软件搭建FTP服务器,使用QFTP模块访问FTP服务器
已经介绍了Qt环境下搭建FTP服务器或者使用QFTP上传的方式示例,
这里主要介绍下使用QFTP模块上传整个文件夹的案例示例。

目录导读

    • 前因后果
    • 单线程处理
      • 1.定义FTPFolderUpload 继承 QThread线程类
      • 2.等待FTP中的命令执行完毕
      • 3.遍历本地文件夹上传文件夹
    • 生产者消费者模式
      • 1. 定义一个UploadItme 结构用于数据交互,
      • 2. 定义生产者方法,
      • 3. 定义消费者
      • 4. 定义缓存区
      • 5. 开始线程调用

前因后果

一开始听到使用QFTP模块上传文件夹这个需求的时候,我还觉得简单,没啥难度,无非是遍历文件夹,上传文件罢了,能有多大问题,
于是我在界面上创建文件再上传文件,正常上传没问题,
但是当我遍历文件目录,按照手动创建文件夹的流程一条条写入mkdir(),cd(),put() 命令时,软件直接崩了。
不知道是由于执行的命令太多,还是上传的文件QFile* 太多了造成的,也没有用QBreakpad捕捉崩溃,
既然按照手动操作的方式上传是没有问题,那么
事急从权
所以为了五一假期能耍舒服点,手动正常上传那么我就参照手动上传的模式,
等上一个命令执行完了,在执行下一条命令,
给FTP客户端一个反应时间,以避免文件夹还没创建就开始上传文件了。
于是通过qftp.h头文件找到 QFtp::hasPendingCommands()函数判断上一条命令是否执行完毕。
于是
既: 通过循环休眠判断当前FTP客户端中的命令是否执行完毕。

// QFtp* FtpClient;qint64 count=1;while(FtpClient->hasPendingCommands()){// qDebug()<<count<<".hasPendingCommands--> "<<QDateTime::currentDateTime()<<""<<FtpClient->state();//! 等待所有命令完成 这里的数值调小有助于提速,但是过小那么循环的意义不大msleep(100);count++;//! 如果链接时间超过30秒则异常if(count>s && s!=-1)return false;}return true;

但是这样一来就有个问题,如果在主界面这么做,会直接把QFTP的事件堵塞,也就是一直卡着,不会执行命令,一开始没注意,多次测试堵塞了FTP客户端的事件执行,导致连FTP服务器都没连上。
于是我创建了一个继承QThread线程的类,在这个线程类内监控QFtp类的命令项是否执行完毕,执行完毕就继续遍历本地文件夹,在FTP服务器创建文件夹和上传文件。

单线程处理

在新的QThread类中处理的时候,唯一要注意的就是FTP客户端所在线程不能一致,
所以需要先在主界面创建一个QFTP*类变量(FTP客户端),再传递给QThread线程类处理。

  • 1.定义FTPFolderUpload 继承 QThread线程类

#include <QObject>
#include <QWidget>
#include <QThread>
#include "qftp.h"//! 等待ftp命令完成
#define WAITFTPOVER       AwaitingExecution()
#define WAITFTPOVERS(_S_) AwaitingExecution(_S_)//! 继承QThread线程
class FTPFolderUpload:public QThread
{Q_OBJECT
public:QThread_FolderUpload(QObject *parent=nullptr);~QThread_FolderUpload();//! 初始化参数void InitData(QFtp* FtpClient,QString ftproot,QString dirpath);void run();//! 返回异常信息QString GetError(){return ErrorStr;};//! 等待当前FTP命令执行完毕//! 避免在没有创建完文件夹前就开始上传文件bool AwaitingExecution(int s=30);//! 遍历文件目录void TraverseTheFolder(QString FtpDir,QString Dirpath);
private://! Ftp服务器的相对位置QString FtpRoot;//! 需要上传的文件夹QString DirPath;//! Ftp客户端QFtp* FtpClient=nullptr;//! 出现异常信息QString ErrorStr;
};
  • 2.等待FTP中的命令执行完毕

等待FTP中的命令执行完毕就是循环判断是否还有未处理的的命令,
如果有则QThread::msleep休眠等待执行完毕

bool FTPFolderUpload::AwaitingExecution(int s)
{if(FtpClient==nullptr)return false;qint64 count=1;while(FtpClient->hasPendingCommands()){//! 等待所有命令完成 这里的数值调小有助于提速,msleep(100);count++;//! 如果链接时间超过30秒则异常 -设置一个默认时间if(count>s && s!=-1)return false;}return true;
}
  • 3.遍历本地文件夹上传文件夹

遍历本地文件夹,同时上传文件,每次上传文件或者创建文件夹时都需要等待前面所有的命令执行完毕,
否则上传的文件很可能上传到其他文件夹或者服务器根目录中

void FTPFolderUpload::TraverseTheFolder(QString FtpDir,QString dirpath)
{	FtpClient->cd
http://www.xdnf.cn/news/306325.html

相关文章:

  • 基于GA遗传优化的不同规模城市TSP问题求解算法matlab仿真
  • 如何在 Ubuntu 24.04 本地安装 DeepSeek ?
  • STM32H743单片机实现ADC+DMA多通道检测
  • Python生活手册-Numpy数组索引:从快递柜到咖啡店的数字化生活指南
  • 易境通货代系统:如何用一套系统解决货代多业务场景痛点?
  • 机器学习-简要与数据集加载
  • 影刀RPA中使用AI模型
  • java中hashmap源码解析(jdk1.8)
  • 代码mark:脚本获取包含全角字符的字符串的长度
  • php中serialize和unserialize的用法详解
  • 开源模型应用落地-qwen模型小试-Qwen3-8B-推理加速-vLLM-Docker(二)
  • 鸿蒙NEXT开发动画(风格的弹性缩放加载动画组件)
  • 长实公布新盘案名“花语海” 打造全新“维港都会公园圈”
  • Dubbo(99)如何在区块链系统中应用Dubbo?
  • RLOO:将多次其他回答的平均reward作为baseline
  • [250505] Arch Linux 正式登陆 Linux 的 Windows 子系统
  • 电动金属硬密封蝶阀泄露等级:水、蒸汽、油品介质的零泄漏守护方案-耀圣
  • Relay 算子调用流程
  • Java 函数式编程
  • 高斯计校准的重要性
  • 【C语言】推箱子小游戏
  • 初步认识java
  • 精益数据分析(42/126):移动应用商业模式的深度剖析与实战要点
  • 浏览器存储 Cookie,Local Storage和Session Storage
  • 在 Sheel 中运行 Spark:开启高效数据处理之旅
  • 公司项目架构搭建者
  • LXwhat-嘉立创
  • 5G+教育:如何重塑未来课堂?
  • 打造智慧养老实训室,构建科技赋能养老新生态
  • 精益数据分析(44/126):深度解析媒体网站商业模式的关键要点