头文件ftp.h
#pragma once
#ifdef CREATEDELL_API_DU
#else
#define CREATEDELL_API_DU _declspec(dllexport)
#endif
#ifndef FTPCLIENT_H
#include <QtCore\QString>
#include <QtNetwork\QNetworkAccessManager>
#include <QtNetwork\QNetworkRequest>
#include <QtNetwork\QNetworkReply>
#include <QtCore\QUrl>
#include <QtCore\QFile>
#include <QtCore\QDir>
#include <QtCore\QDebug>
#include <QtCore\QObject>
#include <memory>
class CREATEDELL_API_DU FtpClient : public QObject
{
Q_OBJECT
public:
explicit FtpClient(QObject *parent = 0);
virtual ~FtpClient();
void setUrl();
void setDir(const QString& dirpath);
void setFile(QString& filename);
void setPort(int port = 21);
void setPath(QString& path);
void setHost(QString& ip);
void setPassword(QString& password);
void setUserName(QString& username);
void setPercent(qint64 bytesSent, qint64 bytesTotal);
QNetworkReply::NetworkError getErrorCode();
void FtpClient::setErrorCode(QNetworkReply::NetworkError errors);
public slots:
void upload();
void download(int& errCode);
void readContent();
void replyFinished(QNetworkReply*);
void loadError(QNetworkReply::NetworkError);
void loadProgress(qint64 bytesSent, qint64 bytesTotal);
public:
virtual void onFinish() {}
virtual qint64 getPersent()
{
return percent_;
}
private:
QNetworkReply *reply_;
std::shared_ptr<QFile> file_;
std::shared_ptr<QUrl> url_;
std::shared_ptr<QDir> dir_;
std::shared_ptr<QNetworkAccessManager> accessManager_;
qint64 percent_;
QNetworkReply::NetworkError error_;
};
#endif // FTPCLIENT_H
源文件ftp.cpp
#define CREATEDELL_API_DU _declspec(dllexport)
#include "ftp.h"
#include <iostream>
#include <QEventLoop>
CREATEDELL_API_DU FtpClient::FtpClient(QObject *parent) :
QObject(parent), percent_(0)
{
url_ = std::make_shared<QUrl>();
url_->setScheme("ftp");
}
CREATEDELL_API_DU FtpClient::~FtpClient()
{
}
QNetworkReply::NetworkError FtpClient::getErrorCode()
{
return this->error_;
}
void FtpClient::setErrorCode(QNetworkReply::NetworkError errors)
{
this->error_ = errors;
}
void CREATEDELL_API_DU FtpClient::setDir(const QString& dirPath)
{
dir_ = std::make_shared<QDir>(dirPath);
if (!dir_->exists())
{
auto ok = dir_->mkdir(dirPath);
if (!ok)
{
qDebug() << "make dir " << dirPath << " failed..." << endl;
}
}
}
void CREATEDELL_API_DU FtpClient::setUrl()
{
url_ = std::make_shared<QUrl>();
url_->setScheme("ftp");
}
void CREATEDELL_API_DU FtpClient::setFile(QString& fileName)
{
file_ = std::make_shared<QFile>(dir_->absolutePath() + "/" + fileName);
}
void CREATEDELL_API_DU FtpClient::setPort(int port)
{
if (nullptr != url_)
{
url_->setPort(port);
}
}
void CREATEDELL_API_DU FtpClient::setPercent(qint64 sendBytes, qint64 totalBytes)
{
double result = 100.0 * sendBytes / totalBytes;
this->percent_ = (int)result;
}
void CREATEDELL_API_DU FtpClient::setPassword(QString& password)
{
if (nullptr != url_)
{
url_->setPassword(password);
}
}
void CREATEDELL_API_DU FtpClient::setUserName(QString& userName)
{
if (nullptr != url_)
{
url_->setUserName(userName);
}
}
void CREATEDELL_API_DU FtpClient::setPath(QString& path)
{
url_->setPath(path);
}
void CREATEDELL_API_DU FtpClient::setHost(QString& ip)
{
url_->setHost(ip);
}
void CREATEDELL_API_DU FtpClient::upload()
{
qDebug() << "upload file " << *file_ << " begin..." << endl;
if (!file_->open(QIODevice::ReadOnly))
{
qDebug() << "open file " << *file_ << " failed..." << endl;
}
//创建一个QNetworkAccessManager实例,将accessManager指向它
accessManager_ = std::make_shared<QNetworkAccessManager>(this);
accessManager_->setNetworkAccessible(QNetworkAccessManager::Accessible);
QNetworkRequest request(*url_);
reply_ = accessManager_->put(request, file_.get());
connect(accessManager_.get(), SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)),Qt::DirectConnection);
connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)),Qt::DirectConnection);
connect(reply_, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(loadProgress(qint64, qint64)),Qt::DirectConnection);
}
void CREATEDELL_API_DU FtpClient::download(int& errCode)
{
errCode = 0;
qDebug() << "download file " << *file_ << " begin..." << endl;
file_->open(QIODevice::WriteOnly);
accessManager_ = std::make_shared<QNetworkAccessManager>(this);
accessManager_->setNetworkAccessible(QNetworkAccessManager::Accessible);
QNetworkRequest request(*url_);
reply_ = accessManager_->get(request);
connect(reply_, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
[=, &errCode](QNetworkReply::NetworkError code)
{
file_->close();
switch ((int)code)
{
case QNetworkReply::ConnectionRefusedError:
qDebug() << "ConnectionRefusedError";
break;
case QNetworkReply::HostNotFoundError:
qDebug() << "HostNotFoundError";
break;
case QNetworkReply::TimeoutError:
qDebug() << "TimeoutError";
break;
case QNetworkReply::AuthenticationRequiredError:
{
qDebug() << "AuthenticationRequiredError";
errCode = code;
break;
}
default:
{
errCode = code;
break;
}
}
});
connect((QObject *)reply_, SIGNAL(readyRead()), this, SLOT(readContent()));
connect((QObject*)(accessManager_.get()), SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)),Qt::DirectConnection);
//connect(reply_, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)),Qt::DirectConnection);
connect(reply_, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(loadProgress(qint64, qint64)),Qt::DirectConnection);
QEventLoop eventloop;
connect((QObject*)(accessManager_.get()), SIGNAL(finished(QNetworkReply*)), &eventloop, SLOT(quit()));
eventloop.exec(QEventLoop::ExcludeUserInputEvents);
}
void CREATEDELL_API_DU FtpClient::readContent()
{
file_->write(reply_->readAll());
}
void CREATEDELL_API_DU FtpClient::replyFinished(QNetworkReply* replys)
{
if (reply_->error() == QNetworkReply::NoError)
{
qDebug() << "end..." << endl;
reply_->deleteLater();
file_->flush();
file_->close();
//发送传输完成信号
onFinish();
}
else
{
//QMessageBox::critical(NULL, tr("Error"), "Failed!!!");
qDebug() << "Error Failed!!!" << endl;
}
}
void CREATEDELL_API_DU FtpClient::loadError(QNetworkReply::NetworkError)
{
qDebug() << "Error: " << reply_->error();
setErrorCode( reply_->error());
}
void CREATEDELL_API_DU FtpClient::loadProgress(qint64 bytesSend, qint64 bytesTotal)
{
setPercent(bytesSend, bytesTotal);
qDebug() << "loaded" << bytesSend << "of" << bytesTotal << " " << getPersent() << "%";
}