当前位置: 首页 > news >正文

建站之星好不计算机编程培训学校哪家好

建站之星好不,计算机编程培训学校哪家好,帝国cms调用网站地址,加强政协网站建设目录 上传文件功能的实现 uploadtask的设计 设置上传的槽函数 uploadFileAction接口 uploadFile接口 定时上传文件 进度条的设计 上传文件功能的实现 上传文件功能实现 1.双击 ”上传文件 “的 QListWidgetItem 或者 点击 “上传” 菜单项 都会弹出一个文件对话框 2.在文…

目录

上传文件功能的实现

uploadtask的设计

设置上传的槽函数

uploadFileAction接口

 uploadFile接口

定时上传文件

进度条的设计


上传文件功能的实现

上传文件功能实现

1.双击 ”上传文件 “的 QListWidgetItem 或者 点击 “上传” 菜单项 都会弹出一个文件对话框

 2.在文件对话框选中对应的文件,保存所有文件的路径(在对话框中可以选中多个文件)

3.将对应的文件存放到  uploadtask* m_uploadtask中(uploadtask 是一个上传文件队列类型

4.定义m_uploadTimer定时器,每0.5秒调用 uploadFileAction 进行上传文件。

5.uploadFileAction中先发送一个 md5 http请求给服务器

  • 如果文件存在服务器,则 秒传成功,不需要将文件内容发送到服务器上
  • 如果文件不存在服务器,则再发送一个upload的请求,将文件的内容上传到服务器上。

6.妙传失败,调用 uploadFile 接口,将文件内容上传到服务器上。

uploadtask的设计

1.UploadFileInfo 是上传文件的信息的结构体


#define UPLOAD_NOT          0   //未上传
#define UPLOADING           1   //正在上传
#define UPLOAD_FINISHED     2   //上传完成
#define UPLOAD_FAILD        3   //上传失败
#define UPLOAF_FILE_EXISTE  4   //上传的文件已存在struct UploadFileInfo
{QString md5;            //文件的md5值QString fileName;       //文件名称QString filePath;       //文件路径qint64 size;            //文件大小FileDataProgress *fdp;  //进度条int uploadStatus;       //0.未上传,1.正在上传,2.上传完成
};

2.UploadTask上传任务 列表类,该 任务列表 存储的是即将上传的文件的信息 UploadFileInfo

//uploadtask.h文件//上传任务列表类, 单例模式
class UploadTask
{
public ://获取UploadTask唯一实例对象static UploadTask* getInstance();//添加文件到上传任务列表中int appendUploadTask(QString filePath);//判断任务列表是否为空bool isEmpty();//取出任务UploadFileInfo* takeTask();//删除任务void delUploadTask();//清空上传任务列表列表void clearList();
private:UploadTask();~UploadTask();//静态数据成员,类中声明,类外必须定义static UploadTask* m_instance;
private:QList<UploadFileInfo*> m_fileList;
};//uploadtask.cpp文件//添加文件到上传任务列表中
int uploadtask::appendUploadTask(QString filePath)
{QFileInfo* fileinfo=new QFileInfo(filePath);if(fileinfo->size()>30*1024*1024){//如果文件大于30mb,则放弃该文件delete fileinfo;return -1;}//新建一个UploadFileInfo对象UploadFileInfo* uploadFileInfo=new UploadFileInfo;uploadFileInfo->size=fileinfo->size();uploadFileInfo->fileName=fileinfo->fileName();uploadFileInfo->filePath=filePath;uploadFileInfo->md5=Common::getInstant()->getFileMd5(filePath);uploadFileInfo->uploadStatus=UPLOAD_NOT;//设置未上传状态filedataProgress* upProgress=new filedataProgress;upProgress->setName(uploadFileInfo->fileName);uploadFileInfo->fdp=upProgress;//将进度条插入到上传列表中uploadlayout::getInstant()->getVLayout()->insertWidget(0,upProgress);m_filelist.append(uploadFileInfo);
}//判断任务列表是否为空
bool uploadtask::isEmpty()
{return m_filelist.empty();
}//取出任务
UploadFileInfo* uploadtask::takeTask()
{if(m_filelist.empty()){return nullptr;}UploadFileInfo* temp=m_filelist.at(0);return temp;
}//删除任务
void uploadtask::delUploadTask()
{//1.取出任务,判断该任务的状态,如果是上传完成,上传失败,上传成功,该任务是会被删除掉//2.将该任务从列表中移除//3.删除进度条,并删除该任务的资源if(isEmpty()){return;}UploadFileInfo* temp=m_filelist.at(0);if(temp->uploadStatus==UPLOAD_FINISHED||temp->uploadStatus==UPLOAD_FAILD||temp->uploadStatus==UPLOAF_FILE_EXISTE  ){//删除该任务qDebug()<<"删除任务";m_filelist.removeAt(0);//将进度条从布局中移除uploadlayout::getInstant()->getVLayout()->removeWidget(temp->fdp);delete temp->fdp;delete temp;}
}//清空任务列表
void uploadtask::clearList()
{int len=m_filelist.size();for(int i=0;i<len;i++){UploadFileInfo* temp=m_filelist.at(0);m_filelist.removeAt(0);uploadlayout::getInstant()->getVLayout()->removeWidget(temp->fdp);//将进度条从布局中移除delete temp->fdp;delete temp;}
}

设置上传的槽函数

点击 “上传文件" 的QListWidgetItem,将文件的上传任务 添加 到 上传队列中。

//设置“上传文件”QListWidgetItem的槽函数
//双击QListWidget窗口中的控件,则会发出一个itemDoubleClicked信号
connect(ui->listWidget,&QListWidget::itemDoubleClicked,this,[=](QListWidgetItem *item){if(item->text()=="上传文件"){addUploadFile();}});//设置“上传”菜单项的槽函数connect(m_uploadAction,&QAction::triggered,this,[=]{addUploadFile();qDebug()<<"上传";
});//添加上传文件
void myfile::addUploadFile()
{//getOpenFileNames可以获取多个文件的路径QStringList filelist=QFileDialog::getOpenFileNames();for(int i=0;i<filelist.size();i++){//将文件添加到m_uploadtask中int res=m_uploadtask->appendUploadTask(filelist[i]);if(res==-1){//服务器设置最多只能上传30m大小的文件QMessageBox::warning(this,"警告","文件大小大于30m");}}
}

uploadFileAction接口

  • uploadFileActionm_uploadtask获取一个UploadFileInfo对象
  • 在根据UploadFileInfo对象信2息发送一个 HTTP请求给服务器去验证文件是否存在
POST http://119.23.41.13:80/md5 HTTP/1.1
Content-Type: application/json{"fileName": "111.rtf", //文件名"md5": "8274425de767b30b2fff1124ab54abb5",//文件md5值,标识文件的唯一性"token": "7b4b4922958c5cbb153df2668b714144",//验证用户身份"user": "zhangsan"//用户信息
}

客户端根据服务器返回的 code 做出相应的动作。 

​
"code":"005"  //上传的文件已存在(别的用户正在上传该文件)
"code":"006"  //秒传成功,文件已经存在
"code":"007"  // 秒传失败,文件不存在,需要调用uploadFile上传文件,
"code":"011"   //"Token 验证失败,身份过期​

 

//获取m_uploadtask中的一个上传任务
void myfile::uploadFileAction()
{if(m_uploadtask->isEmpty()){//任务列表为空// qDebug()<<"任务列表为空";return;}UploadFileInfo* uploadFileInfo=m_uploadtask->takeTask();//先进行快传,判断文件是否已经上传成功//封装http请求//如果该文件没有上传,则发送请求if(uploadFileInfo->uploadStatus==UPLOAD_NOT){uploadFileInfo->uploadStatus=UPLOADING;QNetworkRequest request;//从配置文件中获取到ip地址和port端口号QString ip=Common::getInstant()->getConfValue("web_server","ip");QString port=Common::getInstant()->getConfValue("web_server","port");QString url = QString("http://%1:%2/md5").arg(ip).arg(port);request.setUrl(QUrl(url));//设置文件类型request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));//将data数据以QJson的格式发送给服务器QJsonObject object;object.insert("user", m_logininfo->user());object.insert("token", m_logininfo->token());object.insert("md5",uploadFileInfo->md5);object.insert("fileName",uploadFileInfo->fileName);QJsonDocument doc(object);QByteArray data=doc.toJson();//发送请求// qDebug()<<data;QNetworkReply* rely=m_manager->post(request,data);connect(rely,&QNetworkReply::readyRead,this,[=]{//响应到达,读取所有的数据QByteArray s=rely->readAll();qDebug() << "服务器返回数据:" << QString(s);//将s数据转换为Json对象QJsonParseError err;QJsonDocument document=QJsonDocument::fromJson(s,&err);if(err.error!=QJsonParseError::NoError){qDebug()<<"QJson格式错误";return;}//将QJson字符串转换为QJson对象QJsonObject object1;object1=document.object();//获取状态码QString value1=object1["code"].toString();if(value1=="005"){qDebug()<<"文件已经存在";//文件正在上传uploadFileInfo->uploadStatus=UPLOAF_FILE_EXISTE;Common::getInstant()->writeRecord(m_logininfo->user(),uploadFileInfo->fileName,value1);m_uploadtask->delUploadTask();return;}if(value1=="006"){uploadFileInfo->uploadStatus=UPLOAF_FILE_EXISTE;Common::getInstant()->writeRecord(m_logininfo->user(),uploadFileInfo->fileName,value1);m_uploadtask->delUploadTask();qDebug()<<"妙传成功";}if(value1=="007"){//qDebug()<<"上传文件";//文件没有上传到服务器上,需要将文件上传到服务器上uploadFile(uploadFileInfo);}if(value1=="111"){Common::getInstant()->writeRecord(m_logininfo->user(),uploadFileInfo->fileName,value1);qDebug()<<"token验证失败";}});}
}

 uploadFile接口

uploadFile是发送一个 http请求 将文件中数据发送给服务器,服务器会将其进行保存。

POST http://119.23.41.13:80/upload HTTP/1.1
Content-Type: application/json------WebKitFormBoundaryNr0Jm9D3w0GCiG9g //文件边界线
Content-Disposition: form-data; user="zhangsan" filename="111.rtf" md5="8274425de767b30b2fff1124ab54abb5" size=7
Content-Type: application/octet-stream文件数据
------WebKitFormBoundaryNr0Jm9D3w0GCiG9g //文件边界线

服务器返回值:

"code":"008"
"code":"009"

 

//将文件上传到服务器上
/*
------WebKitFormBoundaryDQAR0QX1ojAyzAre\r\n
Content-Disposition: form-data; name="file"; filename="logo.png"\r\n
Content-Type: image/png\r\n
\r\n
真正的文件内容\r\n
------WebKitFormBoundaryDQAR0QX1ojAyzAre
*/
//将文件内容上传到服务器上
void myfile::uploadFile(UploadFileInfo *uploadFileInfo)
{QFile file(uploadFileInfo->filePath);file.open(QIODevice::ReadOnly | QIODevice::Text);logininfoinstance *login = logininfoinstance::getInstant();//getBoundary接口是随机生成一个文件边界线QString boundary = m_common->getBoundary();QByteArray data;data.append(boundary);data.append("\r\n");data.append("Content-Disposition: form-data; ");data.append(QString("user=\"%1\" filename=\"%2\" md5=\"%3\" size=%4").arg(login->user()).arg(uploadFileInfo->fileName).arg(uploadFileInfo->md5).arg(uploadFileInfo->size));data.append("\r\n");data.append("Content-Type: application/octet-stream");data.append("\r\n");data.append("\r\n");//上传中的数据data.append(file.readAll());data.append("\r\n");data.append(boundary);//文件边界线if (file.isOpen()) {file.close();}QString url = QString("http://%1:%2/upload").arg(login->ip()).arg(login->port());QNetworkRequest request;request.setUrl(url);request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));//发送http请求QNetworkReply *reply = m_manager->post(request, data);if (reply == NULL) {qDebug() << "请求失败";return;}//显示文件上传进度connect(reply, &QNetworkReply::uploadProgress, this, [=](qint64 bytesSent, qint64 bytesTotal){//bytesSent 上传的字节数//bytesTotal 文件需要上传的总字节数if (bytesTotal != 0) {//显示进度条(设置进度条)uploadFileInfo->fdp->setValue(bytesSent, bytesTotal);}});connect(reply, &QNetworkReply::finished, this, [=](){//文件上传完成后if (reply->error() != QNetworkReply::NoError) {qDebug() << reply->errorString();} else {QByteArray s=reply->readAll();/*008: 上传成功009: 上传失败*///响应到达,读取所有的数据// qDebug() << "服务器返回数据:" << QString(s);//将s数据转换为Json对象QJsonParseError err;QJsonDocument document=QJsonDocument::fromJson(s,&err);if(err.error!=QJsonParseError::NoError){qDebug()<<"QJson格式错误";return;}//将QJson字符串转换为QJson对象QJsonObject object1;object1=document.object();//获取状态码QString value1=object1["code"].toString();if (value1== "008") {qDebug() << "上传成功";uploadFileInfo->uploadStatus=UPLOAD_FINISHED;getFileCount(Normal);} else if (value1 == "009") {uploadFileInfo->uploadStatus=UPLOAD_FAILD;qDebug() << "上传失败";}//将传输记录记录到文件中Common::getInstant()->writeRecord(login->user(),uploadFileInfo->fileName,value1);//   writeRecord(QString user, QString fileName, QString code, QString path)}m_uploadtask->delUploadTask();reply->deleteLater();});
}

 

定时上传文件

定义一个定时器,定时器每0.5秒 调用一次uploadFileAction函数,

    //设置每0.5秒调用uploadFileActionm_uploadTimer.start(500);connect(&m_uploadTimer,&QTimer::timeout,this,[=](){uploadFileAction();});

进度条的设计

自定义一个进度条类型filedataProgress ,包括filedataProgress.h ,filedataProgress.cpp,filedataProgress.ui 文件.

filedataProgress.ui界面设计:

        

 

//filedataProgress.cpp文件
//设置文件名
void filedataProgress::setName(QString name)
{ui->label->setText(name);
}
//设置进度条数据
void filedataProgress::setValue(int value,int maxValue)
{ui->progressBar->setValue(value*100/maxValue);
}

当上传任务添加到上传列表时,就将进度条显示到 上传列表中,等待客户端上传文件。

uploadFile接口 中需要设置 QNetWorkReply的uploadProgress信号,将上传的进度显示到进度条上。。QNetWorkReply每 当上传一次文件数据,则会发出uploadProgress信号 

注意: bytesTotal 不能为 0,如果为 0,则会崩溃。

        //显示文件上传进度connect(reply, &QNetworkReply::uploadProgress, this, [=](qint64 bytesSent, qint64 bytesTotal){//bytesSent 上传的字节数//bytesTotal 文件需要上传的总字节数if (bytesTotal != 0) {//显示进度条(设置进度条)uploadFileInfo->fdp->setValue(bytesSent, bytesTotal);}});

http://www.bjxfkj.com.cn/article/102221.html

相关文章:

  • 网络运维工程师简历关键词搜索优化
  • 上海网站制作建设是什么成都网站快速排名
  • 湘潭自助建站系统广州seo网络优化公司
  • 购物类网站建设方案沈阳网站优化
  • 合肥网页设计公司校企合作seo门户网
  • 手机网站搭建教程爱站网长尾词挖掘工具
  • David网站做kegg分析步骤火蝠电商代运营公司
  • 做网站的学校有哪些百度站长工具查询
  • 建网站 视频的网址快速排名seo软件
  • 如何给网站流量来源做标记通过在网址后边加问号?seo外链怎么发
  • 网站视频上传怎么做网络营销论文3000字
  • 怎么自己做网站链接培训机构需要什么资质
  • 做消费信贷网站seo怎么做关键词排名
  • 新冠流行最新消息站长工具seo源码
  • 做微信小程序网站百度推送
  • 兰州网站建设实验总结seo入门书籍推荐
  • 网站怎么做百度推广可口可乐网络营销案例
  • 怎么创建视频号seo专业培训
  • 搜索不到的网站高端seo服务
  • 个人建个网站多少钱韩国网站
  • qq可以做公司免费网站现在推广平台哪家最好
  • 深圳网站建设的基本知识网站seo排名优化价格
  • 个人专业制作网站百度软件下载安装
  • 免费做ppt的网站乔拓云网站注册
  • 无锡网站制作平台谷歌浏览器app下载
  • 成都网站seo推广seo就业指导
  • 郑州做网站公司排网站关键词排名批量查询
  • 最便宜做公司网站正规软件开发培训学校
  • 做公司网站哪家好网络营销类型有哪些
  • 通辽市做网站公司廊坊网站排名优化公司哪家好