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

Qt5移除了QFtp API,原因是其实现质量,QNetworkAccessManager可以用来提供ftpurl的上传下载操作; 但是美中不足的是QNetworkAccessManager没有提供list()、cd()、remove()、mkdir()、rmdir()、rename() 和 rawCommand()等操作。 先来看看操作结果: ...
本来是打算用新的类QNetworkAccessManager实现的客户端的文件上传下载、新建文件夹、重命名、删除和刷新等功能,但是QNetworkAccessManager没有提供原本在QFtp提供的list()、cd()、remove()、mkdir()、rmdir()、rename() 和 rawCommand()等操作,所以无奈之下只能选用了旧版本的QFtp实现,毕竟既然官方都废弃了QFtp而选用QNetworkAccessManager来代替,那肯定是后者比前者更加可靠稳定。          虽然QFtpQt5.0之后就被官方移除了,但是其基本功能还是挺全的,虽然在上传下载文件的时候带中文时会乱码,但也是能解决的。         最近在做一个项目也是用到了QFtp上传文件到别人的服务器,突然就想到了要做一个简单的客户端实现其基本的功能,于是在闲暇时就慢慢的把功能给加上去了,虽然有点简陋但是还是实现了有不少的功能,当然也包括了前面提到上传下载带中文的文件乱码问题。
QT5之后,访问FTP服务器就没有了QFtp,都是使用QNetworkAccessManager访问FTP,其代码和访问HTTP服务器是差不多的,只是在设置url时需要添加用户名密码以及端口号,不多说上代码。 #ifndef FTPCLIENT_H #define FTPCLIENT_H #include <QObject> #include <QNetwork...
因为项目需要,第一次接触到FTP的上传问题,经过查阅后摈弃了旧的QFtp,采用新的QNetworkAccessManager。有关它的使用其实也很方便,已经提供了比较成熟的接口和信号,下面总结一下。首先,在头文件创建一些变量和指针 url是之后需要上传的FTP服务器文件路径;QNetworkAccessManager 就是所谓的网络访问管理器,主要靠它来进行文件上传;QNetworkReply 是QNetworkAccessManager 上传时的一个回复对象,可以通过它来得到一些返回的信息然后,是cpp文
前文已经介绍了Qt项目中实现FTP上传文件的三种实现方式,今天主要看QFtp实现,以及接口在使用过程中需要注意的问题避坑。 首先我们要知道ftp服务器端的IP地址,以及端口号,前面我们介绍到FTP协议有两种方式,主动模式和被动模式(这里不做过多介绍,感兴趣的可以去查阅相关资料),通常开发都是使用被动模式,这种比较简单,由服务器端默认端口地址为21,客户端连接。 接着需要登录ftp的账号和密码,知道这几个数据后就可以连接服务器了。 我们看一下相关接口: QFtp ftp; ftp.connect
Qt是一种功能强大的跨平台应用程序框架,包含很多内置类和函数库,其中QNetworkAccessManagerQt中处理网络请求的重要类。此外,QNetworkAccessManager还可以用于实现FTP协议。 首先,需要创建一个QNetworkAccessManager对象,并使用QUrl类来表示FTP服务器的URL地址。然后,调用QNetworkAccessManager类的get函数来向FTP服务器发送请求。在这里,可以通过QNetworkRequest类的setUrl函数来设置请求URL。 下载文件时,可以使用reply()函数获取服务器响应,并使用QFile类打开本地文件,最后使用QIODevice::write()函数来写入文件。 上传文件时,可以使用QNetworkRequest类的setHeader函数来设置上传文件的元数据信息,如文件名和文件大小等。然后,使用QFile类打开本地文件,并使用QHttpMultiPart类将文件内容添加到请求体中。最后,调用QNetworkAccessManager类的post函数发送请求,并使用reply()函数获取服务器响应。 总之,Qt中QNetworkAccessManager提供了完整的FTP访问功能,可以方便地实现FTP上传和下载文件操作,并且具有很好的跨平台性。