https 大文件分块上传思路总结

https内容就不讲了,网上内容很多,也可以观看以前总结下来的内容。

Qt https 配置以及介绍:https://blog.csdn.net/bloke_come/article/details/103479714

上传思路:

  1. 为了更加快速上传需要先建一个预读线程
  2. 制作发送表单
  3. 如果服务器不支持组包,那么要增加一个变量用来判断是否能发送下一次

具体代码:

	// 线程预读部分
	QFile file(  /*文件路径*/    );
    if(!file.open(QIODevice::ReadOnly) || !file.exists())
    {
        file.close();
        m_isOpenSuccess = false;
        return;
    }

	// 获取文件大小,并计算最多是多少块
    qint64 iSize = file.size();
    m_iChuncks  = iSize  % g_iChunkSize == 0 ? 0 : 1;
    m_iChuncks = (m_SliceInfo.iSize / g_iChunkSize) + iChunks;
    
    while (!file.atEnd())
    {
        msleep(10);
        if(m_isStopUpload)
        {
            file.close();
            return;
        }
        if(
                (-1 == m_iChunckThread) ||
                (m_listFileChunck.size() >= 5)
           )
        {
            msleep(50);
            continue;
        }

		// 跳转到需要读几块,光标移动到0的位置目的是为了放置读取错误,基本不耗时
        file.seek(0);
        file.seek(g_iChunkSize * m_iChunckThread);
        QByteArray array = file.read(g_iChunkSize);
        ++m_iChunckThread;

        std::unique_lock lock(m_mutex);
        m_listFileChunck.push_back(array);
    }

    file.close();

变量解释:

m_isOpenSuccess :打开文件失败标志
g_iChunkSize : 设置的块大小
iChuncks : 总共分了多少块
m_iChunckThread:续传时应该读第几块
m_listFileChunck:已读到的内容存放容器,这里规定不大于5块时才需要继续预读
m_isStopUpload 停止上传

发送表单

	QNetworkRequest request;
    m_Request.swap(request);

    QString qstrURL = ;
    m_Request.setUrl(qstrURL);

    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

	// 告诉服务器总块数
    QHttpPart chunksPart;
    chunksPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"chunks\""));
    chunksPart.setBody(QString::number(m_iChuncks).toStdString().c_str());
    multiPart->append(chunksPart);

	// 告诉服务器当前是上传第几块
    QHttpPart chunkPart;
    chunkPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"chunk\""));
    chunkPart.setBody(QString::number(iChunck).toStdString().c_str());
    multiPart->append(chunkPart);

	// 告诉服务器上传文件的文件名称
    QHttpPart filePart;
    QString qstrFormat = QString("form-data; name=\"file\"; filename=%1;").arg(m_qstrFileName);
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(qstrFormat));

	// 取对应的块数
    std::unique_lock lock(m_mutex);
    filePart.setBody(m_listFileChunck.front());
    m_listFileChunck.erase(m_listFileChunck.begin());
    multiPart->append(filePart);
    ++m_iChunck;

	// 发送表单
    QNetworkReply *reply = m_AccessManager->post(m_Request, multiPart);
    multiPart->setParent(reply);

无法组包情况下,根据返送判断是否继续发送,还是标记为发送失败

	// 如果成功继续处理
    bool isSuccess = jsonObject["success"].toBool();
    if(isSuccess)
    {
        if(m_iChunck >= m_iChuncks)
        {
        	// 标记为上传完成
        }
        else
        {
        	// 标记为可以继续发送
            m_isCanSendData = true;
            // 计算上传进度
            m_qstrUploadProgress = QString::number((iChunck / (iChuncks * 1.00)) * 100, 'f', 2);
            emit sigUploadProgress(m_qstrUploadProgress );
        }

        return true;
    }

    如果失败,标记为上传失败或者其他待处理逻辑

你可能感兴趣的:(网络编程,QT,qt,https,上传大文件,上传文件表单制作)