一、前言
主要功能如下:
1.实现文件夹的下载和删除,网上很多资料都是单独对某个路径的文件操作的,并不能对文件夹操作
2.实现目标机中含中文名称自动转码,有些系统编码方式不同,下载出来的文件会乱码
3.实现ftp功能保活,在正常使用时ftp如果挂载超过5分钟会自动断开
4.实现ftp复位重连,ftp是官方在qt5舍弃的,因为有bug,登录失败时再次登录就会出现问题,这里也是通过一些方法避免了这个问题,每次登录可重新判断网络和账号密码信息
此资源为qt5.7的代码cpp文件和相关main函数和结构体定义h文件,需要嵌入到自己的程序中修改一下类接口调用部分,并不是一个独立的程序。只要你是真正的软件工程师10000000%能正常使用。
此资源中没有实现的功能如下:
没有做上传功能,因为项目没有使用,用于数据存储设备,定期通过软件导出硬盘下某个总数据的文件夹不同日期的数据,修改起来会很简单,同下载方式差不太多。
没有做目录的进入退出功能,这个功能也很简单,网上也有很多demo
二、环境
windows
qt5.7
三、正文
首先请看VCR,哈哈
注意:速度与网络环境有关,网络条件差的当文件量特别多时可能会出现卡顿、延迟等现象
下面附上一些关键的核心代码
1.复位登录重连方法
//连接设备按键
void appdataoutput::on_btnConn_clicked()
{
//判断账号密码输入栏是否为空,进行错误提示
if(ui->lineEdit_name->text().isEmpty()||ui->lineEdit_passwd->text().isEmpty()){
massage_dialog(1,"提示","设备账户或密码不能为空!",1,30);
return;
}
resetFTP();//复位FTP
clearControls();//清除信息
//判断是否已经登录,如果已经登录了就不需要重复登录
if (m_ftp->state() != QFtp::LoggedIn){
ui->textEdit->append("------------------------");
ui->textEdit->append("正在连接,请确保网络链路正常连通...");
m_ftp->connectToHost(sIP, 21);//设置IP和端口
m_ftp->login(ui->lineEdit_name->text(),ui->lineEdit_passwd->text());//登录账号密码
}
else if(m_ftp->state() != QFtp::Connecting)
massage_dialog(1,"提示","已连接,未登录!",1,30);
else
massage_dialog(1,"提示","已登录,无需重复登录!\n如有异常请退出重新进入!",1,30);
}
//复位FTP
void appdataoutput::resetFTP()
{
m_ftp->state();
m_ftp->abort();
m_ftp->deleteLater();
m_ftp = nullptr;
m_ftp = new QFtp(this);
connect(m_ftp, SIGNAL(dataTransferProgress(qint64, qint64)),SLOT(S_upDateProgress(qint64, qint64))); // 进度条显示
connect(m_ftp, SIGNAL(commandStarted(int)), this,SLOT(ftpCommandStarted(int))); //命令启动
connect(m_ftp, SIGNAL(commandFinished(int, bool)),SLOT(ftpcommandFinish(int, bool))); //命令完成
connect(m_ftp, SIGNAL(stateChanged(int)), this,SLOT(ftpStateChanged(int)));//状态改变
connect(m_ftp, SIGNAL(listInfo(const QUrlInfo&)), this,SLOT(addToList(const QUrlInfo&))); // 添加文件项
connect(m_ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));//完成
}
就是每次登录把之前的ftp关闭掉,重新启动
2.保活方法
///timer定时器初始化 ftp保活
QTimer *time1=new QTimer(this);
time1->start(120*1000);//2分钟执行一次,不发送ftp命令 5分钟自动断开
connect(time1,&QTimer::timeout,[=](){
if(m_FTPconnectflag==2){//判断是否连接成功
QByteArray keepfile=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz").toLatin1();
m_ftp->put(keepfile,toSpecialEncoding(m_keeppath));//向目标设备写入数据,定期保持ftp活跃,避免自动关闭
qDebug()<<"发送程序保活"<<QString(keepfile);
}
});
在初始化时创建定时器,定时判断是否连接成功,连接成功状态下定期向ftp中上传一个文件。
m_FTPconnectflag变量跟随ftp连接状态动态改变
3.编码中英文切换
//转码 从目标机器编码转window中文
QString ftpDownloadDir::fromSpecialEncoding(const QString& inputStr)
{
#ifdef FTP_to_window
QTextCodec* codec = QTextCodec::codecForName("GBK");//UTF-8
return codec->toUnicode(inputStr.toLatin1());
#else
return inputStr.toLatin1();//linux A40i连接需要使用此方式
#endif
}
//转码 从window中文转目标机器编码
QString ftpDownloadDir::toSpecialEncoding(const QString& inputStr)
{
#ifdef FTP_to_window
QTextCodec* codec = QTextCodec::codecForName("GBK");//UTF-8
return QString::fromLatin1(codec->fromUnicode(inputStr));
#else
return QString::fromLatin1(QTextCodec::codecForName("UTF-8")->fromUnicode(inputStr));//linux A40i连接需要使用此方式
#endif
}
在目标机中有的是gbk编码,有的是utf8编码,在window下面是utf8编码,需要把ftp中读取的文件夹或文件含中文编码的转换为window能够识别的,在进入目标机子目录使用cd命令时需要将中文在转