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

永州市开发建设投资有限公司网站重庆企业网站开发

永州市开发建设投资有限公司网站,重庆企业网站开发,重庆欧勒精细陶瓷有限公司网站策划书,山东建设报网站目录 上传文件功能的实现 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.yayakq.cn/news/462224/

相关文章:

  • 网站备案弊端wordpress中的文章
  • 建站软件怎么免费升级详情页模板 套用
  • vue2.0网站开发商城手机网站建设
  • 西安网站建设现状wordpress增加移动端
  • 网站建设多久能学会怎么建立网站
  • 广东做网站的公司有哪些网站是用什么技术做的
  • 网站后台管理程序下载wordpress后天地址
  • 湖北钟祥建设局网站安阳房产网
  • 淄企业网站建设公司免费发布信息网网站
  • 部门网站建设宗旨网站开发流程步骤
  • 建筑工程网站建设wordpress 改错域名
  • asp.net 手机网站模板厦门百度快照优化排名
  • 网站空间商拿不回数据广州开发区外国语学校
  • 龙岗平湖网站建设公司秦皇岛建网站多少钱
  • 郑州手机网站建设多少钱网站运营总监
  • 横沥网站建设做外卖网站的模板
  • 免费 网站 空间青岛做网站报价
  • 专注番禺网站优化手机做兼职的网站有哪些
  • 龙岩网站设计招聘信息深圳企业建设网站
  • 网站常用字号湛江免费建站模板
  • 新的网站设计公司wordpress邮箱订阅
  • 南京网站设计外包合肥住房和城乡建设局
  • 北京网站seo价格网页设计公司有哪些成都
  • 做有关兼职网站的需求分析如何备份网站 整站
  • 建设厅执业资格注册中心网站重庆搜索引擎推广公司
  • 重庆建站模板大全荆州企业网站建设
  • 中国建设银行安徽省分行招聘网站电商是什么工作主要干啥
  • html5 网站模版个人网页设计硬件需求
  • 南通高端网站设计建设网站首页打开速度
  • 做网站用php还是node前端面试题2023