Qt:QNetworkAccessManager使用ftp协议上传文件

编程入门 行业动态 更新时间:2024-10-09 05:24:28

Qt:QNetworkAccessManager使用ftp协议<a href=https://www.elefans.com/category/jswz/34/1770844.html style=上传文件"/>

Qt:QNetworkAccessManager使用ftp协议上传文件

目录

第一种写法

第二种


第一种写法

.h

#pragma once#include <QMainWindow>
#include <QNetworkAccessManager>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();
private:void Init();void Upload();
private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_3_clicked();private:Ui::MainWindow *ui;QStringList files;QNetworkAccessManager * manager = nullptr;
};

.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"#include <QNetworkReply>
#include <QNetworkRequest>
#include <QFileDialog>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);Init();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::Init()
{manager = new QNetworkAccessManager(this);ui->progressBar->setMaximum(100);
}void MainWindow::Upload()
{foreach (QString filepath, files){QUrl remoteUrl("ftp://127.0.0.1:2122/" + QFileInfo(filepath).fileName());QNetworkRequest request(remoteUrl);request.setMaximumRedirectsAllowed(120000); // timeout in millisecondsrequest.setHeader(QNetworkRequest::ContentLengthHeader, QFile(filepath).size());request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");QFile file(filepath);file.open(QIODevice::ReadOnly);QByteArray data = file.readAll();       file.close();QNetworkReply* reply = manager->put(request, data);connect(reply, &QNetworkReply::uploadProgress, [=](qint64 bytesSent, qint64 bytesTotal) {qDebug() << "已上传:" << bytesSent << "字节,总共上传字节:"  << bytesTotal;});connect(reply, &QNetworkReply::finished, [=]() {if(reply->error() != QNetworkReply::NoError) {//error handling}reply->deleteLater();});}
}void MainWindow::on_pushButton_clicked()
{files = QFileDialog::getOpenFileNames(this, "选择上传文件", QDir::homePath(), "Files (*.*)");foreach(QString file, files){ui->textEdit->append(file);}
}void MainWindow::on_pushButton_2_clicked()
{Upload();
}void MainWindow::on_pushButton_3_clicked()
{ui->textEdit->clear();
}

界面:

存在问题:中文命名的文件名称会乱码

第二种

FtpManager.h

#pragma once#include <QObject>#include <QUrl>
#include <QFileInfo>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QTimer>
#include <QDebug>#define DECLARE_INSTANCE_CLASS(className) \
private: \class GC \{ \public: \~GC() \{ \delete className::Instance(); \} \}; \static className * _bll; \
public: \static className * Instance() \{ \static GC _gc; \if (!_bll) \_bll = new className(); \return _bll; \}#define REALIZE_INSTANCE_CLASS(className) \className * className::_bll = nullptr;class FtpManager : public QObject
{Q_OBJECTDECLARE_INSTANCE_CLASS(FtpManager);
public:explicit FtpManager(QObject * parent = nullptr);// 设置地址和端口void SetHostPort(const QString &host, int port = 21);// 设置登录 FTP 服务器的用户名和密码void SetUserInfo(const QString &userName, const QString &password);// 上传文件 同步/阻塞模式 不会发送信号QNetworkReply::NetworkError UploadSync(const QString & srcFilePathName, const QString & ftpFilePathName, int timeoutMSec);QNetworkReply::NetworkError UploadSync(const QByteArray & srcData, const QString & ftpFilePathName, int timeoutMSec);// 下载文件 同步/阻塞模式 不会发送信号QNetworkReply::NetworkError DownloadSync(const QString & ftpFilePathName, const QString & srcFilePathName, int timeoutMSec);QNetworkReply::NetworkError DownloadSync(const QString & ftpFilePathName, QByteArray & srcData, int timeoutMSec);// 上传文件 异步 会发送 UploadProgress UploadFinished Error 信号QNetworkReply * UploadAsync(const QString & srcFilePathName, const QString & ftpFilePathName);QNetworkReply * UploadAsync(const QByteArray & srcData, const QString & ftpFilePathName);QNetworkReply * UploadBigFileAsync(QIODevice * srcData, const QString & ftpFilePathName);// 下载文件 异步 会发送 DownloadProgress DownloadFinished Error 信号QNetworkReply * DownloadAsync(const QString & ftpFilePathName, const QString & srcFilePathName);signals:void Error(QNetworkReply::NetworkError);// 上传进度void UploadProgress(qint64 bytesSent, qint64 bytesTotal);// 下载进度void DownloadProgress(qint64 bytesReceived, qint64 bytesTotal);// 完成,并会delete相关的QNetworkReplyvoid UploadFinished();// 完成,并会delete相关的QNetworkReplyvoid DownloadFinished();private slots:void OnUploadFinished();// 下载过程中写文件void OnDownloadFinished();private:QTimer * StartSingleShotTimer(QTimer * timer, int msec);private:QUrl _FtpUrl;QFile _FileDownload;QNetworkAccessManager _NetworkManager;};

.cpp

#include "FtpManager.h"#include <QEventLoop>REALIZE_INSTANCE_CLASS(FtpManager);
FtpManager::FtpManager(QObject * parent) : QObject(parent)
{// 设置协议_FtpUrl.setScheme("ftp");
}void FtpManager::SetHostPort(const QString &host, int port)
{_FtpUrl.setHost(host);_FtpUrl.setPort(port);
}void FtpManager::SetUserInfo(const QString &userName, const QString &password)
{_FtpUrl.setUserName(userName);_FtpUrl.setPassword(password);
}QNetworkReply::NetworkError FtpManager::UploadSync(const QString & srcFilePathName, const QString & ftpFilePathName, int timeoutMSec)
{QFile file(srcFilePathName);file.open(QIODevice::ReadOnly);QByteArray data = file.readAll();file.close();return UploadSync(data, ftpFilePathName, timeoutMSec);
}QNetworkReply::NetworkError FtpManager::UploadSync(const QByteArray & srcData, const QString & ftpFilePathName, int timeoutMSec)
{_FtpUrl.setPath(ftpFilePathName);QNetworkReply * pReply = _NetworkManager.put(QNetworkRequest(_FtpUrl), srcData);QTimer * timer = StartSingleShotTimer(new QTimer(this), timeoutMSec);QEventLoop eventLoop;connect(timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);connect(pReply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);eventLoop.exec(QEventLoop::ExcludeUserInputEvents);auto err = pReply->error();if (timer->remainingTime() == -1)err = QNetworkReply::TimeoutError;delete timer;pReply->abort();pReply->deleteLater();return err;
}QNetworkReply::NetworkError FtpManager::DownloadSync(const QString & ftpFilePathName, const QString & srcFilePathName, int timeoutMSec)
{QByteArray array;QNetworkReply::NetworkError err = DownloadSync(ftpFilePathName, array, timeoutMSec);if (err == QNetworkReply::NoError){QFile fileDownload(srcFilePathName);fileDownload.open(QIODevice::WriteOnly);fileDownload.write(array);fileDownload.close();}return err;
}QNetworkReply::NetworkError FtpManager::DownloadSync(const QString & ftpFilePathName, QByteArray & srcData, int timeoutMSec)
{_FtpUrl.setPath(ftpFilePathName);QNetworkReply * pReply = _NetworkManager.get(QNetworkRequest(_FtpUrl));QTimer * timer = StartSingleShotTimer(new QTimer(this), timeoutMSec);QEventLoop eventLoop;connect(timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);connect(pReply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);eventLoop.exec(QEventLoop::ExcludeUserInputEvents);QNetworkReply::NetworkError err;if (timer->remainingTime() == -1){err = QNetworkReply::TimeoutError;}else{err = pReply->error();if (err == QNetworkReply::NoError){srcData = pReply->readAll();}}delete timer;pReply->abort();pReply->deleteLater();return err;
}QNetworkReply * FtpManager::UploadAsync(const QString & srcFilePathName, const QString & ftpFilePathName)
{
//    QTime time;
//    time.start();
//    QFile file(srcFilePathName);//    file.open(QIODevice::ReadOnly);
//    QByteArray data = file.readAll();
//    file.close();
//    int t1 = time.elapsed();
//    qDebug() <<"t1 = " << t1;//超过1G的大文件QFile * fileData = new QFile(srcFilePathName, this);if(fileData->open(QIODevice::ReadOnly)){qDebug() << "大文件";return UploadBigFileAsync(fileData, ftpFilePathName);}else{qDebug() << "open error";
//        return UploadAsync(data, ftpFilePathName);}
}QNetworkReply *FtpManager::UploadAsync(const QByteArray &srcData, const QString &ftpFilePathName)
{_FtpUrl.setPath(ftpFilePathName);QNetworkReply * pReply = _NetworkManager.put(QNetworkRequest(_FtpUrl), srcData);connect(pReply, &QNetworkReply::finished, this, &FtpManager::OnUploadFinished);connect(pReply, &QNetworkReply::uploadProgress, this, &FtpManager::UploadProgress);connect(pReply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),this, &FtpManager::Error);return pReply;
}QNetworkReply * FtpManager::UploadBigFileAsync(QIODevice *srcData, const QString & ftpFilePathName)
{_FtpUrl.setPath(ftpFilePathName);QNetworkReply * pReply = _NetworkManager.put(QNetworkRequest(_FtpUrl), srcData);connect(pReply, &QNetworkReply::finished, this, &FtpManager::OnUploadFinished);connect(pReply, &QNetworkReply::uploadProgress, this, &FtpManager::UploadProgress);connect(pReply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),this, &FtpManager::Error);return pReply;
}QNetworkReply * FtpManager::DownloadAsync(const QString & ftpFilePathName, const QString & srcFilePathName)
{_FileDownload.setFileName(srcFilePathName);_FileDownload.open(QIODevice::WriteOnly);_FtpUrl.setPath(ftpFilePathName);QNetworkReply * pReply = _NetworkManager.get(QNetworkRequest(_FtpUrl));connect(pReply, &QNetworkReply::finished, this, &FtpManager::OnDownloadFinished);connect(pReply, &QNetworkReply::downloadProgress, this, &FtpManager::DownloadProgress);connect(pReply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),this, &FtpManager::Error);return pReply;
}void FtpManager::OnUploadFinished()
{QNetworkReply * pReply = qobject_cast<QNetworkReply *>(sender());pReply->deleteLater();pReply = nullptr;emit UploadFinished();
}void FtpManager::OnDownloadFinished()
{QNetworkReply * pReply = qobject_cast<QNetworkReply *>(sender());switch (pReply->error()){case QNetworkReply::NoError:{_FileDownload.write(pReply->readAll());_FileDownload.flush();}break;default:break;}_FileDownload.close();pReply->deleteLater();pReply = nullptr;emit DownloadFinished();
}QTimer * FtpManager::StartSingleShotTimer(QTimer * timer, int msec)
{timer->start(msec);timer->setSingleShot(true);return timer;
}

使用

MainWindow.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"#include <QFileInfo>
#include <QDebug>
#include <QFileDialog>#include "FtpManager.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);ui->progressBar->setValue(0);QString ip = ui->lineEditIP->text().trimmed();int port = ui->spinBoxPort->value();QString userName = ui->lineEditUserName->text().trimmed();QString pwd = ui->lineEditPwd->text().trimmed();connect(&ftpManager, &FtpManager::UploadProgress, this, &MainWindow::SetProgressValue);connect(&ftpManager, &FtpManager::UploadFinished, this, [](){qDebug() << "文件上传完毕";});connect(&ftpManager, &FtpManager::Error, this, [](QNetworkReply::NetworkError err){qDebug() << "出错: " << err;});ftpManager.SetHostPort(ip, port);ftpManager.SetUserInfo(userName, "");//testconnect(FtpManager::Instance(), &FtpManager::UploadProgress, this, &MainWindow::SetProgressValue);connect(FtpManager::Instance(), &FtpManager::UploadFinished, this, &MainWindow::OnUploadFinished);connect(FtpManager::Instance(), &FtpManager::Error, this, [](QNetworkReply::NetworkError err){qDebug() << "出错: " << err;});FtpManager::Instance()->SetHostPort(ip, port);FtpManager::Instance()->SetUserInfo(userName, "");}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{     QString fileName = QFileInfo(ui->lineEditFilePath->text().trimmed()).fileName();QString ftpFileName = "/TestNewFtp/" + fileName;qDebug() << "ftpFileName:" << ftpFileName;qDebug() << "localFileName: " << ui->lineEditFilePath->text().trimmed();time.start();auto err = FtpManager::Instance()->UploadAsync(ui->lineEditFilePath->text().trimmed(), ftpFileName);}void MainWindow::SetProgressValue(qint64 bytesSent, qint64 bytesTotal)
{qDebug() << "已上传:" << bytesSent << "总字节: " << bytesTotal << "进度:" << 100 * (bytesSent / (double)bytesTotal);ui->progressBar->setValue(100 * (bytesSent/ (double)bytesTotal));
}void MainWindow::OnUploadFinished()
{qDebug() << "上传完毕,用时: " << time.elapsed();
}void MainWindow::on_pushButton_2_clicked()
{QString path = QFileDialog::getExistingDirectory(this, tr("选择目录"),"./",QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);if(!path.isEmpty()){ui->lineEditFtpFolder->setText(path);}
}void MainWindow::on_pushButton_3_clicked()
{QString path = QFileDialog::getOpenFileName(this, tr("选择文件"), "./" );if(!path.isEmpty()){ui->lineEditFilePath->setText(path);}
}

中文文件依然会乱码

更多推荐

Qt:QNetworkAccessManager使用ftp协议上传文件

本文发布于:2024-02-19 15:33:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1764567.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:上传文件   协议   Qt   QNetworkAccessManager   ftp

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!