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

使用QNetworkAccessManager实现FTP上传下载功能

自己写了一份FTP的代码,可以上传下载单文件,上传下载多文件,上传目录所有文件,但是下载目录的功能有问题,接口里代码规范也没做(如果有大佬提供修改方案就更好了),代码直接复制可用,留给有需要的人。

#pragma once#include <QObject>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QFile>
#include <QTcpSocket>
#include <QMap>class CFtpMgr : public QObject
{Q_OBJECTpublic:CFtpMgr(QObject* parent = nullptr);~CFtpMgr();void SetFtpAuthority(const QString& strHost, const QString& strName, const QString& strPassword, quint16 nPort = 21);void DownloadFile(const QString& strRemoteFilePath, const QString& strLocalDir);void UploadFile(const QString& strLocalFilePath, const QString& strRemoteDir);void DownloadFiles(const QStringList& listRemoteFilePaths, const QString& strLocalDir);void UploadFiles(const QStringList& listLocalFilePaths, const QString& strRemoteDir);void DownloadDir(const QString& strRemoteDir, const QString& strLocalDir);void UploadDir(const QString& strLocalDir, const QString& strRemoteDir);signals:void SigDownloadProgress(qint64 nReceived, qint64 nTotal);void SigUploadProgress(qint64 nReceived, qint64 nTotal);public slots:void SlotDownloadProgress(qint64 nReceived, qint64 nTotal);void SlotDownloadError(QNetworkReply::NetworkError eError);void SlotDownloadFinished();void SlotUploadProgress(qint64 nReceived, qint64 nTotal);void SlotUploadError(QNetworkReply::NetworkError eError);void SlotUploadFinished();private:void EnsureRemotePathExists(const QString& strRemoteDir);void RecursiveDownloadDir(const QString& strRemoteDir, const QString& strLocalDir);void RecursiveUploadDir(const QString& strLocalDir, const QString& strRemoteDir);private:QUrl m_url;QNetworkAccessManager m_manager;QTcpSocket m_socket;QMap<QNetworkReply*, QFile*> m_mapGetReplies;QMap<QNetworkReply*, QFile*> m_mapPutReplies;
};
#include "FtpMgr.h"
#include <QDir>
#include <QDebug>
#include <QTcpServer>CFtpMgr::CFtpMgr(QObject* parent): QObject(parent)
{m_url.setScheme("ftp");
}CFtpMgr::~CFtpMgr()
{qDeleteAll(m_mapGetReplies);qDeleteAll(m_mapPutReplies);
}void CFtpMgr::SetFtpAuthority(const QString& strHost, const QString& strName, const QString& strPassword, quint16 nPort)
{m_url.setHost(strHost);m_url.setUserName(strName);m_url.setPassword(strPassword);m_url.setPort(nPort);
}void CFtpMgr::DownloadFile(const QString& strRemoteFilePath, const QString& strLocalDir)
{const QString strSaveFileName = strLocalDir + "/" + QFileInfo(strRemoteFilePath).fileName();QFile* pFile = new QFile(strSaveFileName, this);if (pFile->open(QIODevice::WriteOnly)){m_url.setPath(strRemoteFilePath);QNetworkReply* pReply = m_manager.get(QNetworkRequest(m_url));m_mapGetReplies[pReply] = pFile;connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(SlotDownloadProgress(qint64, qint64)));connect(pReply, SIGNAL(finished()), this, SLOT(SlotDownloadFinished()));connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(SlotDownloadError(QNetworkReply::NetworkError)));}else{delete pFile;}
}void CFtpMgr::UploadFile(const QString& strLocalFilePath, const QString& strRemoteDir)
{EnsureRemotePathExists(strRemoteDir);QFile* pFile = new QFile(strLocalFilePath, this);if (pFile->open(QIODevice::ReadOnly)){const QString strSaveFileName = strRemoteDir + "/" + QFileInfo(strLocalFilePath).fileName();m_url.setPath(strSaveFileName);QNetworkReply* pReply = m_manager.put(QNetworkRequest(m_url), pFile);m_mapPutReplies[pReply] = pFile;connect(pReply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(SlotUploadProgress(qint64, qint64)));connect(pReply, SIGNAL(finished()), this, SLOT(SlotUploadFinished()));connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(SlotUploadError(QNetworkReply::NetworkError)));}else{delete pFile;}
}void CFtpMgr::DownloadFiles(const QStringList& listRemoteFilePaths, const QString& strLocalDir)
{foreach(const QString & remoteFilePath, listRemoteFilePaths){DownloadFile(remoteFilePath, strLocalDir);}
}void CFtpMgr::UploadFiles(const QStringList& listLocalFilePaths, const QString& strRemoteDir)
{EnsureRemotePathExists(strRemoteDir);foreach(const QString & localFilePath, listLocalFilePaths){UploadFile(localFilePath, strRemoteDir);}
}void CFtpMgr::DownloadDir(const QString& strRemoteDir, const QString& strLocalDir)
{QDir localDir(strLocalDir);if (!localDir.exists()){localDir.mkpath(".");}RecursiveDownloadDir(strRemoteDir, strLocalDir);
}void CFtpMgr::UploadDir(const QString& strLocalDir, const QString& strRemoteDir)
{RecursiveUploadDir(strLocalDir, strRemoteDir);
}void CFtpMgr::EnsureRemotePathExists(const QString& strRemoteDir)
{m_socket.connectToHost(m_url.host(), m_url.port(21));if (m_socket.waitForConnected()){m_socket.write("USER " + m_url.userName().toUtf8() + "\r\n");m_socket.waitForReadyRead();m_socket.write("PASS " + m_url.password().toUtf8() + "\r\n");m_socket.waitForReadyRead();m_socket.write("MKD " + strRemoteDir.toUtf8() + "\r\n");m_socket.waitForReadyRead();m_socket.disconnectFromHost();}
}void CFtpMgr::RecursiveDownloadDir(const QString& strRemoteDir, const QString& strLocalDir)
{// 接口不可用return;// 以下为测试代码m_url.setPath(m_url.path() + strRemoteDir);QNetworkRequest listRequest(m_url);QNetworkReply* listReply = m_manager.get(listRequest);connect(listReply, &QNetworkReply::finished, listReply, [=](){if (listReply->error() == QNetworkReply::NoError){QString list = listReply->readAll();QStringList lines = list.split("\n");QStringList remoteFiles;QStringList remoteDirs;for (const QString& line : lines){if (line.trimmed().isEmpty()){continue;}// Assuming Unix-style listingchar entryType = line.at(0).toLatin1();QString entryPath = line.mid(55).trimmed();if (entryType == '-'){remoteFiles.append(entryPath);}else if (entryType == 'd'){remoteDirs.append(entryPath);}}QStringList remoteFilePaths;for (const QString& remoteFile : remoteFiles){remoteFilePaths.append(strRemoteDir + remoteFile);}DownloadFiles(remoteFilePaths, strLocalDir);for (const QString& remoteDir : remoteDirs){QString subRemoteFolderPath = strRemoteDir + remoteDir + "/";QString subLocalFolderPath = strLocalDir + remoteDir + "/";RecursiveDownloadDir(subRemoteFolderPath, subLocalFolderPath);}}else{qDebug() << "Error listing directory:" << listReply->errorString();}listReply->deleteLater();});
}void CFtpMgr::RecursiveUploadDir(const QString& strLocalDir, const QString& strRemoteDir)
{QDir localDir(strLocalDir);if (!localDir.exists()){return;}EnsureRemotePathExists(strRemoteDir);QFileInfoList fileInfoList = localDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);for (const QFileInfo& fileInfo : fileInfoList){QString localPath = fileInfo.absoluteFilePath();QString remotePath = strRemoteDir + "/" + fileInfo.fileName();if (fileInfo.isDir()){RecursiveUploadDir(localPath, remotePath);}else if (fileInfo.isFile()){UploadFile(localPath, strRemoteDir);}}
}void CFtpMgr::SlotDownloadProgress(qint64 nReceived, qint64 nTotal)
{emit SigDownloadProgress(nReceived, nTotal);
}void CFtpMgr::SlotDownloadError(QNetworkReply::NetworkError eError)
{qDebug() << "Download Error: " << eError;QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());if (pReply){if (m_mapGetReplies.contains(pReply)){QFile* pFile = m_mapGetReplies.value(pReply);if (pFile){pFile->close();delete pFile;}m_mapGetReplies.remove(pReply);}pReply->deleteLater();}
}void CFtpMgr::SlotDownloadFinished()
{QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());if (pReply){if (m_mapGetReplies.contains(pReply)){QFile* pFile = m_mapGetReplies.value(pReply);if (pFile){pFile->write(pReply->readAll());pFile->close();delete pFile;}m_mapGetReplies.remove(pReply);}pReply->deleteLater();}
}void CFtpMgr::SlotUploadProgress(qint64 nReceived, qint64 nTotal)
{emit SigUploadProgress(nReceived, nTotal);
}void CFtpMgr::SlotUploadError(QNetworkReply::NetworkError eError)
{qDebug() << "Upload Error: " << eError;QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());if (pReply){if (m_mapPutReplies.contains(pReply)){QFile* pFile = m_mapPutReplies.value(pReply);if (pFile){pFile->close();delete pFile;}m_mapPutReplies.remove(pReply);}pReply->deleteLater();}
}void CFtpMgr::SlotUploadFinished()
{QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());if (pReply){if (m_mapPutReplies.contains(pReply)){QFile* pFile = m_mapPutReplies.value(pReply);if (pFile){pFile->close();delete pFile;}m_mapPutReplies.remove(pReply);}pReply->deleteLater();}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 反序列化靶机实战serial(保姆级教程)
  • jupyter for c++
  • java进阶 CompletableFuture
  • Python 设计模式之工厂函数模式
  • stem32江科大自学笔记
  • nodeJS的一点个人总结
  • C语言time库
  • linux shell 脚本 之 getopt
  • 【Mysql】第一章 (环境配置)
  • SpringBoot简单项目(二维码扫描)
  • JVM—虚拟机类加载时机与过程
  • C++之类和对象(上)
  • uniapp打开地图直接获取位置
  • SpringBoot中的server.context-path
  • Spring Boot 整合 Dubbo3 + Nacos 2.4.0【进阶】+ 踩坑记录
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • CSS 专业技巧
  • python学习笔记 - ThreadLocal
  • SpiderData 2019年2月25日 DApp数据排行榜
  • unity如何实现一个固定宽度的orthagraphic相机
  • Vue ES6 Jade Scss Webpack Gulp
  • Web标准制定过程
  • 百度小程序遇到的问题
  • 从零开始在ubuntu上搭建node开发环境
  • 给github项目添加CI badge
  • 机器学习 vs. 深度学习
  • 记一次删除Git记录中的大文件的过程
  • 坑!为什么View.startAnimation不起作用?
  • 前端面试之CSS3新特性
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 推荐一个React的管理后台框架
  • postgresql行列转换函数
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • # linux 中使用 visudo 命令,怎么保存退出?
  • (1)Hilt的基本概念和使用
  • (2)Java 简介
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)iOS字体
  • (转载)利用webkit抓取动态网页和链接
  • .net mvc 获取url中controller和action
  • .Net(C#)自定义WinForm控件之小结篇
  • /dev下添加设备节点的方法步骤(通过device_create)
  • @Async注解的坑,小心
  • @Controller和@RestController的区别?
  • @JsonFormat与@DateTimeFormat注解的使用
  • @KafkaListener注解详解(一)| 常用参数详解
  • @SentinelResource详解
  • [ C++ ] STL---仿函数与priority_queue
  • [AI]ChatGPT4 与 ChatGPT3.5 区别有多大