Qt5.8用HTTP实现文件上传和下载(带进度条)
来源:互联网 发布:信用卡 对比.知乎 编辑:程序博客网 时间:2024/05/29 04:27
Qt5.8用HTTP实现文件上传和下载(带进度条)
本文基于Qt5.8利用HTTP协议实现文件的上传和下载。 本人所使用的HTTP服务器端的操作系统为Linux(Ubuntu),编写QT代码的客户端的操作系统为Windows.
重要声明: 由于QT5.4版本之前和之后所提供的的类的差别非常大,所以请参考本文的读者确保您自己的Qt版本>=5.4。我们主要使用的类QNetWorkAccessManager从5.4版本才开始有。
HTTP服务器(即Apache2)的详细配置可在本人原创的另一篇名为“Ubuntu16.04系统中配置ParaviewWeb5.3+Apache2”的博客中查看(http://blog.csdn.net/timothy93bp/article/details/77509164)。
我的HTTP服务器的用户名为peng, 密码为123456,ip地址为192.168.1.166, HTTP服务器的根目录(即Apache2当前激活的虚拟主机所定义的存放网页文件的目录)为/home/peng/http。
- 1. 与FTP的不同
- 2. UI界面
- 3. 修改.pro文件
- 4. 头文件代码
- 5. 源文件代码(上传,下载,进度条)
- 6. PHP脚本代码
1. 与FTP的不同
用FTP上传和下载的代码可在本人原创的另一篇名为“Qt5.8用FTP实现文件上传和下载(带进度条)”的博客中查看。(http://blog.csdn.net/timothy93bp/article/details/77575079)
使用HTTP不存在考虑内网和外网的问题,但是代码比FTP稍微有点复杂。
HTTP下载的代码与FTP基本相同,但是HTTP上传的代码与FTP的不同主要体现在上传时的请求URL。因为用HTTP上传时,HTTP服务器端需要有一个PHP脚本来响应客户端请求,接收数据并写入文件(如名为upload.php),才能实现上传。
但是HTTP可以实现上传文件到服务器端的某一远程创建的目录中,目录名称由用户指定。若该目录在服务器端已经存在,则直接将文件保存在该目录中;若用户指定名称的目录在服务器中不存在,先远程在服务器上创建该目录,再往该目录中写入文件。这个过程也是由一个PHP脚本实现(如名为createFolder.php)。
所有的PHP脚本都应该放在服务器端,具体是在Apache2当前所激活的虚拟主机定义的存放网页文件的目录中。如该例中,PHP脚本都应该位于/home/peng/http中。
2. UI界面
本程序的UI界面如下:
文本编辑框中输入的是上传到服务器或者下载到本地之后,文件所要保存的名字, 该控件的objectName为“lineEdit“。”FTP上传”的按钮的objectName为“uploadButton“, “FTP下载”的按钮的objectName为“downloadButton“。
3. 修改.pro文件
首先,为了使用关于网络的类,我们首先要在.pro文件中加入一行:QT += network:
//FTP.pro的内容
#-------------------------------------------------## Project created by QtCreator 2017-08-25T14:00:00##-------------------------------------------------QT += core guiQT += networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = HTTPTEMPLATE = app# The following define makes your compiler emit warnings if you use# any feature of Qt which as been marked as deprecated (the exact warnings# depend on your compiler). Please consult the documentation of the# deprecated API in order to know how to port your code away from it.DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.# In order to do so, uncomment the following line.# You can also select to disable deprecated APIs only up to a certain version of Qt.#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += main.cpp\ mainwindow.cppHEADERS += mainwindow.hFORMS += mainwindow.ui
4. 头文件代码
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QString>#include <QNetworkAccessManager>#include <QNetworkRequest>#include <QNetworkReply>#include <QUrl>#include <QFile>#include <QDebug>#include <QMessageBox>#include <QProgressBar>#include <QMainWindow>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow();private slots: void on_uploadButton_clicked(); void on_downloadButton_clicked(); void readContent(); void replyFinished(QNetworkReply*); void loadError(QNetworkReply::NetworkError); void loadProgress(qint64 bytesSent,qint64 bytesTotal);private: Ui::MainWindow *ui; QNetworkReply *reply; QProgressBar *progressBar; QFile *file;};#endif // MAINWINDOW_H
4. 源文件代码
#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this);}MainWindow::~MainWindow(){ delete ui;}void MainWindow::on_uploadButton_clicked() //上传文件{ file = new QFile("C:/Users/Administrator/Desktop/test.jpg"); file->open(QIODevice::ReadOnly); QNetworkAccessManager *accessManager1 = new QNetworkAccessManager(this); //在服务器上创建目录 accessManager1->setNetworkAccessible(QNetworkAccessManager::Accessible); QByteArray data; QUrl url1("http://192.168.1.166:80/createFolder.php?foldername=upload"); QNetworkRequest request1(url1); request1.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/octet-stream")); accessManager1->post(request1, data); QNetworkAccessManager *accessManager2 = new QNetworkAccessManager(this); //往该目录中上传文件 accessManager2->setNetworkAccessible(QNetworkAccessManager::Accessible); QByteArray byte_file = file->readAll(); QUrl url2("http://192.168.1.166:80/upload.php?foldername=upload&filename="+ui->lineEdit->text()+".jpg"); //如这里指定的上传文件至HTTP服务器目录中的upload目录中 QNetworkRequest request2(url2); request2.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream"); reply = accessManager2->post(request2, byte_file); progressBar = new QProgressBar(); progressBar->setValue(0); progressBar->show(); connect(accessManager2,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(loadError(QNetworkReply::NetworkError))); connect(reply, SIGNAL(uploadProgress(qint64 ,qint64)), this, SLOT(loadProgress(qint64 ,qint64)));}void MainWindow::on_downloadButton_clicked() //下载文件{ file = new QFile(QApplication::applicationDirPath() + "/" + ui->lineEdit->text() + ".jpg"); file->open(QIODevice::WriteOnly); QNetworkAccessManager *accessManager = new QNetworkAccessManager(this); accessManager->setNetworkAccessible(QNetworkAccessManager::Accessible); QUrl url("http://192.168.1.166:80/test.jpg"); QNetworkRequest request(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream"); reply = accessManager->get(request); progressBar = new QProgressBar(); progressBar->setValue(0); progressBar->show(); connect((QObject *)reply, SIGNAL(readyRead()), this, SLOT(readContent())); connect(accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(loadError(QNetworkReply::NetworkError))); connect(reply, SIGNAL(downloadProgress(qint64 ,qint64)), this, SLOT(loadProgress(qint64 ,qint64)));}void MainWindow::readContent() //下载时向本地文件中写入数据{ file->write(reply->readAll());}void MainWindow::replyFinished(QNetworkReply*) //删除指针,更新和关闭文件{ if(reply->error() == QNetworkReply::NoError) { reply->deleteLater(); file->flush(); file->close(); } else { QMessageBox::critical(NULL, tr("Error"), "Failed!!!"); }}void MainWindow::loadProgress(qint64 bytesSent, qint64 bytesTotal) //更新进度条{ qDebug() << "loaded" << bytesSent << "of" << bytesTotal; progressBar->setMaximum(bytesTotal); //最大值 progressBar->setValue(bytesSent); //当前值}void MainWindow::loadError(QNetworkReply::NetworkError) //传输中的错误输出{ qDebug()<<"Error: "<<reply->error();}
6. PHP脚本代码
- 1) 在服务器上创建目录的PHP脚本
//createFolder.php
<?php $foldername =$_GET['foldername']; if (!file_exists($foldername)){ mkdir ($foldername); echo 'succeed in creating folder!'; } else { echo 'This folder has existed!'; }?>
“foldername”为用户指定的文件名,比如这里是“upload”。
- 2) 往服务器的该目录下写入文件的PHP脚本
//upload.php
<?php $content = file_get_contents('php://input'); $foldername = $_GET["foldername"]; $filename = $_GET["filename"]; $fp = fopen($foldername."/".$filename,'w+'); fwrite($fp, $content, strlen($content)); fclose($fp);?>
“filename”为用户在UI的lineEdit中输入的文件名+后缀名,也就是文件要存放在服务器上的名字。
以上代码为全部代码,可以直接在客户端的QT上创建一个名为“HTTP”的基于MainWindow的新项目,然后按上述步骤建立ui界面,修改.pro文件,再往.h和.cpp文件中完全复制以上的代码,最后在服务器端http目录中创建“createFolder.php”和“upload.php”文件,并完全复制粘贴以上的代码,点击运行即可。
- Qt5.8用HTTP实现文件上传和下载(带进度条)
- Qt5.8用FTP实现文件上传和下载(带进度条)
- android 文件上传与下载(带进度条)
- 实现http文件下载和上传
- 用servlet实现带进度条的文件上传
- asp.net实现文件上传带进度条(多种风格)
- asp.net实现文件上传带进度条(多种风格)
- asp.net实现文件上传带进度条(多种风格)
- 使用servlet实现简易上传文件(带进度条版本)
- jQuery file upload实现异步文件上传(带进度条)
- spring MVC + bootstrap实现文件上传(带进度条)
- android实现带进度条的文件上传
- XMLHTTPRequest实现带进度条的文件上传
- struts2实现带进度条的文件上传
- ajax实现带进度条的文件上传
- js实现文件上传—带进度条
- Servlet实现带进度条的文件上传
- 带进度条文件上传
- Day13-43.switch
- SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON火狐
- linux解决tomcat内存溢出
- jmeter-察看结果树-响应数据中的中文显示乱码
- [Python] linux下安装Python3.6,与27共存
- Qt5.8用HTTP实现文件上传和下载(带进度条)
- CentOS系统更换软件安装源
- Java-二叉树-插入、删除、遍历
- 计算时间差
- spring boot 系统启动运行的类 MyCommandLineRunner
- Linq To EF 使用小知识(添加记录后获取添加的自增ID和叫“ID”的列不是自增列不让插入的问题)
- 为什么一定要让孩子上名牌大学?这位面试官不小心说出了真相
- 提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
- Linux 使用 rsync 遠端檔案同步與備份工具教學與範例