Qt之QNetworkAccessManager 实现FTP文件上传/下载功能

本文介绍了在Qt5中如何使用QNetworkAccessManager替代QFtp进行FTP文件上传和下载操作,虽然QNetworkAccessManager缺少部分QFtp的函数,但依然可以完成基本任务。文中给出了具体的代码实现,包括上传和下载的示例,并提醒在使用QUrl时需要注意设置'ftp'协议,以及服务器目录的存在性。此外,还提供了源码下载链接和相关FTP服务器搭建教程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简述 

        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

为了在Windows安装ADB工具,你可以按照以下步骤进行操作: 1. 首先,下载ADB工具包并解压缩到你自定义的安装目录。你可以选择将其解压缩到任何你喜欢的位置。 2. 打开运行窗口,可以通过按下Win+R键来快速打开。在运行窗口中输入"sysdm.cpl"并按下回车键。 3. 在系统属性窗口中,选择"高级"选项卡,然后点击"环境变量"按钮。 4. 在环境变量窗口中,选择"系统变量"部分,并找到名为"Path"的变量。点击"编辑"按钮。 5. 在编辑环境变量窗口中,点击"新建"按钮,并将ADB工具的安装路径添加到新建的路径中。确保路径正确无误后,点击"确定"按钮。 6. 返回到桌面,打开命令提示符窗口。你可以通过按下Win+R键,然后输入"cmd"并按下回车键来快速打开命令提示符窗口。 7. 在命令提示符窗口中,输入"adb version"命令来验证ADB工具是否成功安装。如果显示版本信息,则表示安装成功。 这样,你就成功在Windows安装ADB工具。你可以使用ADB工具来执行各种操作,如枚举设备、进入/退出ADB终端、文件传输、运行命令、查看系统日志等。具体的操作方法可以参考ADB工具的官方文档或其他相关教程。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [windows环境安装adb驱动](https://blog.csdn.net/zx54633089/article/details/128533343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Windows安装使用ADB简单易懂教程](https://blog.csdn.net/m0_37777700/article/details/129836351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ilson_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值