Qt上传下载文件

2021-03-10  本文已影响0人  BrokenRainK

详情看代码及注释

头文件

#ifndef HTTPMANAGEMENT_H
#define HTTPMANAGEMENT_H

#include <QObject>
#include <functional>
#include <QNetworkAccessManager>

class HttpManagement : public QObject
{
    Q_OBJECT

public:
    HttpManagement(QObject *parent = 0);

    /**
     * @brief httpGet
     * @param url
     * @param getProgress
     * @param getFinish
     * @param errorHandler
     */
    void httpGet(const QString &url,
                 std::function<void(qint64, qint64)> getProgress,
                 std::function<void(const QString &)> getFinish,
                 std::function<void(const QString &)> errorHandler);

    /**
     * @brief httpPost
     * @param url
     * @param postProgress
     * @param postFinish
     * @param errorHandler
     */
    void httpPost(const QString &url,
                  const QByteArray data,
                  std::function<void(qint64, qint64)> postProgress,
                  std::function<void(const QString &)> postFinish,
                  std::function<void(const QString &)> errorHandler);

    /**
     * @brief httpPut
     * @param url
     * @param putProgress
     * @param putFinish
     * @param putHandler
     */
    void httpPut(const QString &url,
                 const QByteArray data,
                 std::function<void(qint64, qint64)> putProgress,
                 std::function<void(const QString &)> putFinish,
                 std::function<void(const QString &)> errorHandler);

    /**
     * @brief UploadFile
     * @param url
     * @param filePath
     * @param UploadProgress
     * @param UploadFinish
     * @param errorHandler
     */
    void UploadFile(const QString &url,
                    const QString &filePath,
                    std::function<void(qint64, qint64)> UploadProgress,
                    std::function<void(const QString &)> UploadFinish,
                    std::function<void(const QString &)> errorHandler);


    /**
     * @brief DownloadFile
     * @param url
     * @param filePath
     * @param downloadProgress
     * @param downloadFinish
     * @param errorHandler
     */
    void DownloadFile(const QString &url,
                      const QString &filePath,
                      std::function<void(qint64, qint64)> downloadProgress,
                      std::function<void(const QString &)> downloadFinish,
                      std::function<void(const QString &)> errorHandler);

private:
    void httpMethod(const QString &method,
                    const QString &url,
                  const QByteArray data,
                  std::function<void(qint64, qint64)> httpProgress,
                  std::function<void(const QString &)> httpFinish,
                  std::function<void(const QString &)> errorHandler);

private:
    QNetworkAccessManager *m_pNetworkManager;
};

#endif // HTTPMANAGEMENT_H

源文件

#include "httpmanagement.h"
#include <QFile>
#include <QFileInfo>
#include <QHttpPart>
#include <QNetworkReply>
#include <QHttpMultiPart>
#include <QNetworkRequest>

HttpManagement::HttpManagement(QObject *parent)
    : QObject(parent)
    , m_pNetworkManager(new QNetworkAccessManager(this))
{

}

void HttpManagement::httpGet(const QString &url,
                             std::function<void(qint64, qint64)> getProgress,
                             std::function<void(const QString &)> getFinish,
                             std::function<void(const QString &)> errorHandler)
{
    QNetworkRequest request;
    request.setUrl(QUrl(url));

    QNetworkReply *reply = m_pNetworkManager->get(request);
    connect(reply, &QNetworkReply::downloadProgress, [=](qint64 bytesSent, qint64 bytesTotal) {
        if ((reply->error() == QNetworkReply::NoError)
            && (0 != bytesSent) && (0 != bytesTotal))
        {
            getProgress(bytesSent, bytesTotal);
        }
    });
    connect(reply, &QNetworkReply::finished, [=]() {
        if (reply->error() == QNetworkReply::NoError)
        {
            getFinish(reply->readAll());
        }
        reply->deleteLater();
    });
    connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), [=](QNetworkReply::NetworkError) {
        errorHandler(reply->errorString());
        reply->deleteLater();
    });
}

void HttpManagement::httpPost(const QString &url,
                              const QByteArray data,
                              std::function<void(qint64, qint64)> postProgress,
                              std::function<void(const QString &)> postFinish,
                              std::function<void(const QString &)> errorHandler)
{
    httpMethod("post", url, data, postProgress, postFinish, errorHandler);
}

void HttpManagement::httpPut(const QString &url,
                             const QByteArray data,
                             std::function<void(qint64, qint64)> putProgress,
                             std::function<void(const QString &)> putFinish,
                             std::function<void(const QString &)> errorHandler)
{
    httpMethod("put", url, data, putProgress, putFinish, errorHandler);
}

void HttpManagement::UploadFile(const QString &url,
                                const QString &filePath,
                                std::function<void(qint64, qint64)> UploadProgress,
                                std::function<void(const QString &)> UploadFinish,
                                std::function<void(const QString &)> errorHandler)
{
    QFile *pFile = new QFile(filePath);
    if (!pFile->open(QIODevice::ReadOnly))
    {
        errorHandler(QStringLiteral("open file fail"));
        return;
    }

    QFileInfo info(filePath);
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart filePart;
    filePart.setBodyDevice(pFile);
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"file\"; filename=\"%1\"").arg(info.fileName()));

    pFile->setParent(multiPart);
    multiPart->append(filePart);

    QNetworkRequest request;
    request.setUrl(QUrl(url));
    QNetworkReply *reply = m_pNetworkManager->post(request, multiPart);
    multiPart->setParent(reply);
    connect(reply, &QNetworkReply::uploadProgress, [=](qint64 bytesSent, qint64 bytesTotal) {
        if ((reply->error() == QNetworkReply::NoError)
            && (0 != bytesSent) && (0 != bytesTotal))
        {
            UploadProgress(bytesSent, bytesTotal);
        }
    });
    connect(reply, &QNetworkReply::finished, [=]() {
        if (reply->error() == QNetworkReply::NoError)
        {
            UploadFinish(QString());
        }
        reply->deleteLater();
    });
    connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), [=](QNetworkReply::NetworkError) {
        errorHandler(reply->errorString());
        reply->deleteLater();
    });
}

void HttpManagement::DownloadFile(const QString &url,
                                  const QString &filePath,
                                  std::function<void(qint64, qint64)> downloadProgress,
                                  std::function<void(const QString &)> downloadFinish,
                                  std::function<void(const QString &)> errorHandler)
{
    if (filePath.isEmpty())
    {
        errorHandler(QStringLiteral("filePath isEmpty"));
        return;
    }

    QFile *file = new QFile(filePath);
    if (!file->open(QIODevice::WriteOnly))
    {
        file->deleteLater();
        errorHandler(QStringLiteral("open file fail"));
        return;
    }

    QNetworkRequest request;
    request.setUrl(QUrl(url));
    //    request.setRawHeader("Content-Type", "binary; charset=utf-8");
    QNetworkReply *reply = m_pNetworkManager->get(request);
    file->setParent(reply);
    connect(reply, &QNetworkReply::downloadProgress, [=](qint64 bytesSent, qint64 bytesTotal) {
        if ((reply->error() == QNetworkReply::NoError)
            && (0 != bytesSent) && (0 != bytesTotal))
        {
            file->write(reply->readAll());
            downloadProgress(bytesSent, bytesTotal);
        }
    });
    connect(reply, &QNetworkReply::finished, [=]() {
        if (reply->error() == QNetworkReply::NoError)
        {
            downloadFinish(QString());
        }
        reply->deleteLater();
    });
    connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), [=](QNetworkReply::NetworkError) {
        errorHandler(reply->errorString());
        reply->deleteLater();
    });
}

void HttpManagement::httpMethod(const QString &method,
                                const QString &url,
                                const QByteArray data,
                                std::function<void(qint64, qint64)> httpProgress,
                                std::function<void(const QString &)> httpFinish,
                                std::function<void(const QString &)> errorHandler)
{
    if (data.isEmpty() || url.isEmpty())
    {
        errorHandler(QStringLiteral("data or url isEmpty"));
        return;
    }

    QNetworkRequest request;
    request.setUrl(QUrl(url));

    QNetworkReply *reply = nullptr;
    if ("put" == method)
    {
        reply = m_pNetworkManager->put(request, data);
    } 
    else if ("post" == method)
    {
        reply = m_pNetworkManager->post(request, data);
    }
    else
    {
        errorHandler(QStringLiteral("Unknown method"));
        return;
    }
    
    connect(reply, &QNetworkReply::uploadProgress, [=](qint64 bytesSent, qint64 bytesTotal) {
        if ((reply->error() == QNetworkReply::NoError)
            && (0 != bytesSent) && (0 != bytesTotal))
        {
            httpProgress(bytesSent, bytesTotal);
        }
    });
    connect(reply, &QNetworkReply::finished, [=]() {
        if (reply->error() == QNetworkReply::NoError)
        {
            httpFinish(QString());
        }
        reply->deleteLater();
    });
    connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), [=](QNetworkReply::NetworkError) {
        errorHandler(reply->errorString());
        reply->deleteLater();
    });
}
上一篇下一篇

猜你喜欢

热点阅读