网盘—下载文件

news/2024/10/17 2:31:51/

本文主要讲解网盘文件操作的下载文件部分,具体步骤如下:

目录

1、实施步骤

2、代码实现

2.1、添加下载文件的协议

2.2、添加下载文件函数

2.3、添加信号槽

2.4、实现槽函数

2.5、设置download状态

2.6、添加定义

2.7、服务器接收数据

2.8、添加下载文件的case

2.9、测试——看一下客户端是否可以得到文件名和大小

A、点击下载文件,保存在桌面

B、终端输出,文件名字和大小

2.10、提取文件名和大小

2.11、收数据

2.12、服务器怎么发数据

2.12、发送文件给客户端

2.13、定义定时器,关联信号槽

2.14、发送文件给客户端

3、测试

3.1、点击需要下载的文件

3.2、选择保存路径已经名称 叫做testt.h

3.3、在桌面查看是否成功下载


1、实施步骤

A、客户端发送下载请求(请求包含路径,下载文件名)

B、服务器提取指定内容以及文件大小发送给客户端

C、客户端循环接收服务器发送过来的文件内容,保存到文件中(客户端需要指定一个位置来保存我们接收到的文件内容,QFileDialog)

2、代码实现

2.1、添加下载文件的协议

    ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST,  //下载文件请求ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND,  //下载文件回复

2.2、添加下载文件函数

    //下载文件void downloadFile();

2.3、添加信号槽

    //关联下载文件槽函数connect(m_pDownLoadPB, SIGNAL(clicked(bool)),this, SLOT(downloadFile()));

2.4、实现槽函数

void Book::downloadFile()
{//获得下载的文件名字//获得当前所在的目录QString strCurPath = TcpClient::getinstance().curPath();//获得点击删除的文件QListWidgetItem *pItem =  m_pBookListW->currentItem();//判断if(NULL==pItem){QMessageBox::warning(this,"下载文件","请选择要下载的文件");}else{//可能还没有输入路径的时候就已经回复了,所以放在前面        //定义存放位置QString strSaveFilePath = QFileDialog::getSaveFileName();if(strSaveFilePath.isEmpty()){QMessageBox::warning(this, "下载文件","请指定要保存的位置");strSaveFilePath.clear();}else {m_strSaveFilePath = strSaveFilePath;}//当前网盘所在的路径QString strCurPath = TcpClient::getinstance().curPath();PDU *pdu =mkPDU(strCurPath.size()+1);pdu->uiMsgType=ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST;//文件名字QString strFileName = pItem->text();strncpy((char*)(pdu->caData),strFileName.toStdString().c_str(),strFileName.size());memcpy(pdu->caMsg,strCurPath.toStdString().c_str(),strCurPath.size());//发送给服务器TcpClient::getinstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);//可能还没有输入路径的时候就已经回复了}
}

2.5、设置download状态

    //设置download的状态void setDownloadStatus(bool status);

2.6、添加定义

void Book::setDownloadStatus(bool status)
{m_bDownload =status;
}

2.7、服务器接收数据

2.8、添加下载文件的case

           //-----------下载文件--------------------------case ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST:{//先把路径名字得到char caFileName[32] = {'\0'};strcpy(caFileName,pdu->caData);//产生一块空间,将传过来的路径拷贝出来char *pPath = new char[pdu->uiMsgLen];memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);QString strPath = QString("%1/%2").arg(pPath).arg(caFileName);qDebug()<<strPath;//释放空间delete [] pPath;pPath = NULL;//服务器给回复//先发送一个大小QFileInfo fileinfo(strPath);qint64 filesize = fileinfo.size();PDU *respdu =mkPDU(0);respdu->uiMsgType = ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND;sprintf(respdu->caData,"%s %lld",caFileName,filesize);//发送给客户端write((char*)respdu,respdu->uiPDULen);free(respdu);respdu = NULL;  break;}

2.9、测试——看一下客户端是否可以得到文件名和大小

        //---------------------下载文件文件------------------------case ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND:{qDebug()<<pdu->caData;//QMessageBox::information(this,"下载文件",pdu->caData);break;}

A、点击下载文件,保存在桌面

B、终端输出,文件名字和大小

2.10、提取文件名和大小

        case ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND:{qDebug()<<pdu->caData;//QMessageBox::information(this,"下载文件",pdu->caData);//定义文件的名字char caFileName[32] ={'\0'};sscanf(pdu->caData, "%s %lld", caFileName, &(OpeWidget::getInstance().getBook()->m_iTotal));if(strlen(caFileName)>0 &&OpeWidget::getInstance().getBook()->m_iTotal >0){OpeWidget::getInstance().getBook()->setDownloadStatus(true);//现在处于下载状态//打开文件m_file.setFileName(OpeWidget::getInstance().getBook()->getSaveFilePath());if(!m_file.open(QIODevice::WriteOnly)){QMessageBox::warning(this, "下载文件","获得保存文件的路径失败");   }}break;}

2.11、收数据

 else {//处于收数据的状态QByteArray buffer = m_tcpSocket.readAll();m_file.write(buffer);Book *pBook = OpeWidget::getInstance().getBook();pBook->m_Recived+=buffer.size();if(pBook->m_iTotal ==pBook->m_Recived){m_file.close();pBook->m_iTotal =0;pBook->m_Recived =0;pBook->setDownloadStatus(false);}else if(pBook->m_iTotal ==pBook->m_Recived) {//收到的数据比原本的数据还要大m_file.close();pBook->m_iTotal =0;pBook->m_Recived =0;pBook->setDownloadStatus(false);QMessageBox::critical(this, "下载文件","下载文件失败");}}

2.12、服务器怎么发数据

2.12、发送文件给客户端

//发送文件数据给客户端void sendFileToClient();

2.13、定义定时器,关联信号槽

    m_pTimer = new QTimer;    connect(m_pTimer, SIGNAL(timeout()), this, SLOT(sendFileToClient()));

2.14、发送文件给客户端

void MyTcpSocket::sendFileToClient()
{char *pData =new char[4096];qint64 ret =0;while (true) {ret = m_file.read(pData, 4096);if(ret>0 &&ret <=4096){write(pData,ret);}else if (0==ret) {//所有文件都读取出来,并且发送完了m_file.close();break;}else if (ret<0) {qDebug()<<"发送文件内容给客户端过程中失败";m_file.close();break;}}delete [] pData;pData = NULL;
}

3、测试

3.1、点击需要下载的文件

3.2、选择保存路径已经名称 叫做testt.h

3.3、在桌面查看是否成功下载

发现桌面有哦

成功!!!!!!!!


http://www.ppmy.cn/news/1448477.html

相关文章

C语言中的指针常量和常量指针

指针常量和常量指针是C/C编程语言中两个重要的概念&#xff0c;它们都与指针有关&#xff0c;但具有不同的含义和用途。 1. 指针常量&#xff08;Pointer to Constant&#xff09; 指针常量指的是一个指针的值&#xff08;即它所指向的地址&#xff09;在初始化之后不能再被改…

vue 组件组件通信方法

1、父组件props传值给子组件。 子组件中定义props字段&#xff0c;类型为Array&#xff08;如需限制字段值类型&#xff0c;也可以定义为Object的形式&#xff09;。如下例子&#xff0c;父组件挂载子组件helloWorld&#xff0c;在组件标签上给title赋值&#xff0c;子组件hel…

【项目纪实】某国有航空公司人力资源系统诊断咨询项目

公司的人力资源管理问题一直都比较严重&#xff0c;比如人员冗余、员工工作积极性差等问题&#xff0c;虽然经过多次的管理尝试&#xff0c;存在的问题仍然没有缓解。华恒智信人力资源咨询公司的老师特别专业&#xff0c;帮我们系统、全面的诊断了人力资源管理上存在的问题&…

LabVIEW智能变电站监控系统设计与实现

LabVIEW智能变电站监控系统设计与实现 随着电力系统和智能化技术的快速发展&#xff0c;建立一个高效、可靠的变电站监控系统显得尤为重要。通过分析变电站监控系统的需求&#xff0c;设计了一个基于LabVIEW软件的监控平台。该平台利用虚拟仪器技术、传感器技术和无线传输技术…

Django后台项目开发实战六

日志记录 第六阶段 日志处理教程 Django 日志处理 我这里实现一个简单的日志&#xff0c;在 setting.py 文件添加日志 LOGGING {# 版本version: 1,# 是否禁止默认配置的记录器disable_existing_loggers: False,formatters: {simple: {format: %(asctime)s %(name)-12s %(linen…

JavaScript 的基本术语大全

文章目录 1、概述2、基本术语2.1、有效负载 (Payload)2.2、ReadableStream2.3、模块系统2.4、DOM (Document Object Model)2.5、事件 (Events)2.6、活动委托 (Event Delegation)2.7、内容安全策略 (CSP)2.8、渐进增强和优雅降级2.9、JSON (JavaScript Object Notation)2.10、AJ…

Web后端开发中对三层架构解耦之控制反转与依赖注入

内聚与耦合 内聚 比如说我们刚刚书写的员工的实现类 在这里我们仅仅书写的是和员工相关的代码 而与员工无关的代码都没有放到这里 说明内聚程度较高 耦合 以后软件开发要高内聚 低耦合 提高程序灵活性 扩拓展性 分析代码 如何解耦 创建容器 提供一个容器 存储东西 存储E…

Ansible playbook之变量引用

1.Ansible facts facts是一个用于采集被管理机器设备信息的一个组件&#xff0c;我们可以使用setup模块查机器的所有facts信息&#xff0c;可以使用filter来查看指定信息。 [rootansible01 ~]# ansible 11.0.1.19 -m setup 11.0.1.19 | SUCCESS > {"ansible_facts&quo…