简述
Qt5移除了QFtp API,原因是其实现质量,QNetworkAccessManager 可以用来提供 ftp url 的上传下载操作; 但是美中不足的是QNetworkAccessManager没有提供list()、cd()、remove()、mkdir()、rmdir()、rename() 和 rawCommand()等操作。
效果
代码
首先封装了类是为了方便调用,减少代码重复:
#ifndef MYFTPMANAGER_H
#define MYFTPMANAGER_H
#include <QUrl>
#include <QObject>
#include <QNetworkReply>
#include <QNetworkAccessManager>
class MyFtpManager : public QObject
{
Q_OBJECT
public:
explicit MyFtpManager(QObject *parent = 0);
QNetworkReply *put(const QString &localPath, const QString &uploadPath);
QNetworkReply *get(const QString &downloadPath, const QString &localPath);
inline void setPort(int port) { url.setPort(port); }
inline void setHost(const QString &host) { url.setHost(host); }
inline void setPath(const QString &path) { url.setPath(path); }
inline void setUserName(const QString &userName) { url.setUserName(userName); }
inline void setPassword(const QString &password) { url.setPassword(password); }
public slots:
void uploadFinished();
void downloadFinished();
void error(QNetworkReply::NetworkError error);
private:
QUrl url;
QString path;
QNetworkAccessManager manager;
};
#endif // MYFTPMANAGER_H
#include "MyFtpManager.h"
#include <QFile>
#include <QNetworkRequest>
MyFtpManager::MyFtpManager(QObject *parent) :
QObject(parent)
{
// 设置协议
url.setScheme("ftp");
}
QNetworkReply *MyFtpManager::put(const QString &localPath, const QString &uploadPath)
{
// 文件是否可以打开
QFile file(localPath);
if (!file.open(QIODevice::ReadOnly))
return NULL;
// 设置上传路径
url.setPath(uploadPath);
QNetworkReply *pReply = manager.put(QNetworkRequest(url), file.readAll());
connect(pReply, SIGNAL(finished()), SLOT(uploadFinished()));
connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(error(QNetworkReply::NetworkError)));
return pReply;
}
QNetworkReply *MyFtpManager::get(const QString &downloadPath, const QString &localPath)
{
// 记录要保存的位置
path = localPath;
// 设置下载路径
url.setPath(downloadPath);
QNetworkReply *pReply = manager.get(QNetworkRequest(url));
connect(pReply, SIGNAL(finished()), SLOT(downloadFinished()));
connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(error(QNetworkReply::NetworkError)));
return pReply;
}
void MyFtpManager::uploadFinished()
{
}
void MyFtpManager::downloadFinished()
{
QNetworkReply *pReply = qobject_cast<QNetworkReply *>(sender());
if (pReply == NULL)
return;
// 如果有错误就不需要保存
if (pReply->error() != QNetworkReply::NoError)
return;
// 写入文件
QFile file(path);
if (!file.open(QIODevice::WriteOnly))
return;
file.write(pReply->readAll());
file.flush();
file.close();
}
void MyFtpManager::error(QNetworkReply::NetworkError error)
{
qDebug() << error;
}
在MainWnd中声明一个成员变量manager,然后在造函数中初始化它:
manager.setHost("192.168.43.5"); // 设置服务器IP地址
manager.setPort(21); // 设置端口
manager.setUserName("zhangsan"); // 设置用户名
manager.setPassword("000000"); // 设置密码
在点击上传按钮时,把某一个路径下的所有图片都上传到FTP服务器指定的路径下:
void MainWnd::on_tbUpload_clicked()
{
QDir dir("F:/Pictrue");
QStringList filter;
filter << "*.jpg" << "*.bmp" << "*.png";
QList<QFileInfo> list = QList<QFileInfo>(dir.entryInfoList(filter));
foreach (QFileInfo info, list)
{
QNetworkReply *pReply = manager.put(info.filePath(), QString("/picture/%1").arg(info.fileName()));
connect(pReply, SIGNAL(uploadProgress(qint64,qint64)), SLOT(uploadProgress(qint64,qint64)));
}
}
在点击下载按钮时,只是单纯的下载某一张图像到程序根目录:
void MainWnd::on_tbDownload_clicked()
{
QNetworkReply *pReply = manager.get("/picture/DSCF21061.jpg", "./DSCF21061.jpg");
connect(pReply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(downloadProgress(qint64,qint64)));
}
然后就是通过信号槽更新进度条:
void MainWnd::uploadProgress(qint64 byteSend, qint64 byteTotal)
{
ui->pgbUpload->setMaximum(byteTotal);
ui->pgbUpload->setValue(byteSend);
}
void MainWnd::downloadProgress(qint64 byteSend, qint64 byteTotal)
{
ui->pgbDownload->setMaximum(byteTotal);
ui->pgbDownload->setValue(byteSend);
}
注意
1. 使用QUrl时需要设置'ftp'协议,否则会提示以下的错误:
2. 在点击上传时,要上传的目录必须存在,也就是说这里上传的目录"/picture"是事先在服务器创建好的;如果服务器中不存在这个目录它不会主动帮你创建,会提示以下的错误:
QNetworkReply::NetworkError(ContentAccessDenied)
源码下载1(折扣):https://item.taobao.com/item.htm?ft=t&id=702584276003
源码下载2(无折扣):https://download.csdn.net/download/Ilson_/19418875
Windows下FTP服务器搭建:https://blog.csdn.net/Ilson_/article/details/97818689
QFtp在客户端实现给服务器一次性创建多级目录:https://blog.csdn.net/Ilson_/article/details/98654137
QFtp实现文件上传、下载、新建文件夹、重命名、删除和刷新等功能:https://blog.csdn.net/Ilson_/article/details/98371848