网盘—下载文件

news2024/12/28 5:57:33

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

目录

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.coloradmin.cn/o/1636480.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【docker】Docker开启远程访问

将构建的镜像自动上传到服务器。 需要开放 Docker 的端口&#xff0c;让我们在本地能连接上服务器的 Docker&#xff0c;这样&#xff0c;才能上传构建的镜像给 Docker。 开启远程访问 首先在服务器打开 Docker 的服务文件 vim /usr/lib/systemd/system/docker.service修改…

ubuntu下安装配置python3.11

方案1 添加仓库&#xff1a; $ sudo add-apt-repository ppa:deadsnakes/ppa $ sudo apt update $ sudo apt install python3.11然后查看有多少个python版本已经安装了&#xff1a; ls -l /usr/bin/python*python2.7,python 3.8 ,python 3.11. 然后&#xff0c;设置系统默认…

贪吃蛇小游戏(c语言)

1.效果展示 屏幕录制 2024-04-28 205129 2.基本功能 • 贪吃蛇地图绘制 • 蛇吃食物的功能 &#xff08;上、下、左、右方键控制蛇的动作&#xff09; • 蛇撞墙死亡 • 蛇撞自身死亡 • 计算得分 • 蛇身加速、减速 • 暂停游戏 3.技术要点 C语言函数、枚举、结构…

VPot-Free一款功能强大的文字转语音工具 v2306

01 软件介绍 VPot-FREE是一款功能强大的免费文字转语音工具&#xff0c;为用户提供了便捷的语音合成功能。无论是想将文字转化为语音进行朗读&#xff0c;还是将文章转为语音保存&#xff0c;VPot-FREE都能满足你的需求。 多种语音风格可供选择&#xff0c;包括男声、女声以及…

C语言-嵌入式-STM32:FreeRTOS说明和详解

Free即免费的&#xff0c;RTOS的全称是Real time operating system&#xff0c;中文就是实时操作系统。 注意&#xff1a;RTOS不是指某一个确定的系统&#xff0c;而是指一类操作系统。比如&#xff1a;uc/OS&#xff0c;FreeRTOS&#xff0c;RTX&#xff0c;RT-Thread 等这些都…

如何利用快解析远程访问NAS、FTP、Web服务

什么是内网、外网&#xff1f; 所谓内网就是内部建立的局域网络或办公网络。一家公司或一个家庭有多台计算机&#xff0c;他们利用不同网络布局将这一台或多台计算机或其它设备连接起来构成一个局部的办公或者资源共享网络&#xff0c;我们就称它为内部网络&#xff0c;也叫内…

【MySQL精炼宝库】深度解析索引 | 事务

目录 一、索引 1.1 索引(index)概念&#xff1a; 1.2 索引的作用&#xff1a; 1.3 索引的缺点&#xff1a; 1.4 索引的使用场景&#xff1a; 1.5 索引的使用&#xff1a; 1.6 面试题:索引底层的数据结构&#xff08;核心内容&#xff09;&#xff1a; 1.7 索引列查询(主…

FSNotes for Mac v6.7.1中文激活:轻量级笔记管理工具

FSNotes for Mac&#xff0c;一款专为Mac用户打造的轻量级笔记管理工具&#xff0c;让您的笔记管理变得简单而高效。 FSNotes for Mac v6.7.1中文激活版下载 它采用Markdown文件格式&#xff0c;让您轻松创建和编辑富文本笔记&#xff0c;无需担心格式问题。同时&#xff0c;FS…

手写一个uart协议——rs232(未完)

先了解一下关于uart和rs232的基础知识 文章目录 一、RS232的回环测试1.1模块整体架构1.2 rx模块设计1.2.1 波形设计1.2.2代码实现与tb1.2.4 仿真 1.3 tx模块设计1.3.1波形设计 本篇内容&#xff1a; 一、RS232的回环测试 上位机由串口助手通过 rx 线往 FPGA 发 8 比特数据&a…

复杂度(3)

目录 1.二分查找的时间复杂度 2.斐波那契数列及其优化 3.空间复杂度 1.二分查找的时间复杂度 我们熟知的二分查找绝对是一种很厉害的算法&#xff0c;因为这个算法每进行一次都会砍掉一半的数据&#xff0c;相当于是指数级增长&#xff0c;假设我们刚开始的时候数据的个数是…

【对比学习】【论文翻译】Contrastive Multiview Coding

Contrastive Multiview Coding ECCV 2020 0.论文摘要和作者信息 摘要 人类通过许多感官通道观察世界&#xff0c;例如&#xff0c;由左眼观察的长波长光通道&#xff0c;或由右耳听到的高频振动通道。每个视图都是嘈杂和不完整的&#xff0c;但重要的因素&#xff0c;如物理…

【linux-1-Ubuntu常用命令-vim编辑器-Vscode链接ubuntu远程开发】

目录 1. 安装虚拟机Vmare和在虚拟机上安装Ubuntu系统&#xff1a;2. 常用的Ubuntu常识和常用命令2.1 文件系统结构2.2 常用命令2.3 vim编辑器 3. Ubuntu能联网但是ping不通电脑&#xff1a;4. Windows上安装VScode链接ubuntu系统&#xff0c;进行远程开发&#xff1a; 1. 安装虚…

Meltdown 以及Linux KPTI技术简介

文章目录 前言一、Introduction二、 Background2.1 Out-of-order execution2.2 Address Spaces2.3 Cache Attacks 三、A Toy Example四、Building Blocks of the Attack4.1 Executing Transient Instructions4.2 Building a Covert Channel 五、Meltdown5.1 Attack Description…

如何使用Spring Boot导出数据到Excel表格

在开发应用程序时&#xff0c;经常会遇到将数据导出到Excel表格的需求。Spring Boot提供了简单而有效的方法来实现这个功能。本文将介绍如何使用Spring Boot和Apache POI库将数据导出到Excel表格&#xff0c;并提供一个示例代码来演示该过程。 1. 准备工作 首先&#xff0c;确…

ARM学习(27)链接库依赖学习(二)dlopen failed:library xxxx.so

笔者继续学习一下链接的依赖库。 1、起因 Android下面需要需要一个日志解码库&#xff0c;所以笔者就编译了一个parse.so来进行解码&#xff0c; 编译器&#xff1a;Clang&#xff0c;基于llvm后端的编译器平台&#xff1a;交叉编译&#xff0c;linux -> aarch64 linux An…

es环境安装及php对接使用

Elasticsearch Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java语言开发的&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是一种流行的…

【LeetCode】拓扑排序——课程表 I II

拓扑排序&#xff1a; AOV网&#xff1a;若用DAG图&#xff08;有向无环图&#xff09;表示一个工程&#xff0c;其顶点表示活动&#xff0c;用有向边<Vi, Vj>表示活动Vi必须先于活动Vj进行的这样一种关系&#xff0c;则将这种有向图称为顶点表示活动的网络&#xff0c;…

餐后血糖波动?学会在米饭里加两物

米饭里加两物&#xff0c;帮你平稳餐后血糖&#xff0c;餐后血糖稳稳的&#xff0c;别让你碗里的米饭太单调&#xff0c;搭着吃对血糖好。今天呢我教大家一招&#xff0c;在蒸米饭的时候&#xff0c;加上两种食材&#xff0c;能够改善餐后血糖。 第一就是在煮米饭的时候加点糙米…

C++多态(全)

多态 概念 调用函数的多种形态&#xff0c; 多态构成条件 1&#xff09;父子类完成虚函数的重写&#xff08;三同&#xff1a;函数名&#xff0c;参数&#xff0c;返回值相同&#xff09; 2&#xff09;父类的指针或者引用调用虚函数 虚函数 被virtual修饰的类成员函数 …

Systemback Ubuntu14.04 制作自定义系统ISO镜像

工作需要&#xff0c;要基于ubuntu自定义一些编译环境并将自己配置好的ubuntu做成镜像。 硬件准备 ​ 为保证能够顺利完成系统iso镜像的制作与系统还原&#xff0c;推荐准备一个较大容量的U盘或者移动固态硬盘&#xff0c;同时确保自己的Ubuntu系统还有比较大的可用空间。 1 S…