网盘—上传文件

news2024/11/26 12:32:10

本文主要讲解网盘里面关于文件操作部分的上传文件,具体步骤如下

目录

1、实施步骤:

2、代码实现

2.1、添加上传文件协议

2.2、添加上传文件槽函数

2.3、添加槽函数定义

2.4、关联上传槽函数

2.5、服务器端

2.6、在服务器端添加上传文件请求的case

2.7、客户端上传内容

2.8、添加定时器

2.9、关联信号槽

2.10、添加槽函数定义

2.11、打开服务器,接收上传文件内容

3、测试

A、点击上传文件,选择文件并打开

 B、提示上传成功

C、发现jack文件夹里面也有了makefile文件

D、大的文件也可以上传


1、实施步骤:

 A、客户端发送上传文件请求,请求包括:包括当前路径上传文件名上传文件内容

包括当前路径,上传文件名,这个时候不上传文件内容,当服务器接收到上传请求之后,在指定的路径下面,将该文件创建出来,客户端发送上传请求之后,上传文件内容。

B、服务器接收到客户端文件内容,将信息保存到之前创建的文件中,在服务器接受完上传的内容之后,服务器发送信息给客户端

C、客户端接受回复信息并显示

2、代码实现

2.1、添加上传文件协议

    ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST,  //上传文件请求
    ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND,  //上传文件回复

2.2、添加上传文件槽函数

    //上传文件
    void uploadFile();

2.3、添加槽函数定义

void Book::uploadFile()
{
    //当前路径
    QString strCurPath = TcpClient::getinstance().curPath();
    //选择上传文件
    //QFileDialog::getOpenFileName();会弹出一个窗口来,类似于打开文件
    QString strUploadFilePath = QFileDialog::getOpenFileName();
    //qDebug()<<strUploadFilePath;
    //将名字提取出来
    if(!strUploadFilePath.isEmpty())
    {
        // aa/bb/cc 5 8
        int index = strUploadFilePath.lastIndexOf('/');
        QString strFileName =strUploadFilePath.right(strUploadFilePath.size()-index-1);
        //qDebug()<<strFileName;
        //将数据封装到PDU里面
        QFile file(strUploadFilePath);
        qint64 filesize = file.size();//获得文件大小
        PDU *pdu =mkPDU(strCurPath.size()+1);
        pdu->uiMsgType=ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST;
        memcpy(pdu->caMsg, strCurPath.toStdString().c_str(),strCurPath.size());
        //"%s %lld" %s文件名 lld文件大小long long 64
        sprintf(pdu->caData,"%s %lld", strFileName.toStdString().c_str(),filesize);
        //发送
        //发送给服务器
        TcpClient::getinstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
        free(pdu);
        pdu=NULL;
    }
    else {
        QMessageBox::warning(this, "上传文件","上传文件名字不能为空!");
    }

}

2.4、关联上传槽函数

    //关联上传文件信号槽
    connect(m_pUpLoadPB,SIGNAL(clicked(bool)),
            this, SLOT(uploadFile()));

2.5、服务器端

添加私有成员

 QFile m_file;
    //文件总的大小
    qint64 m_iTotal;
    qint64 m_iReceived;//每一次接受了多少文件
    bool m_bUpload; //现在处于上传文件状态还是其他状态

2.6、在服务器端添加上传文件请求的case

case ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST:
        {
            char caFileName[32] = {'\0'};
            qint64  fileSize =0;
            //将文件名字提取出来
            sscanf(pdu->caData, "%s %lld", caFileName,&fileSize);
            //产生一块空间,将传过来的路径拷贝出来
            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;
            
            //根据拼接的路径将文件打开
            m_file.setFileName(strPath);
            //以只写的方式打开,如果这个文件不存在的话就会创建这个文件
            if(m_file.open(QIODevice::WriteOnly))
            {
                m_bUpload = true;
                m_iTotal =fileSize;
                m_iReceived = 0;
                
            }
            
            
            break;
        }

2.7、客户端上传内容

2.8、添加定时器

    //创建定时器
    void uploadFileData();    

2.9、关联信号槽

    //关联定时器信号槽
    connect(m_pTimer,SIGNAL(timeout()),
            this, SLOT(uploadFileData()));

2.10、添加槽函数定义

void Book::uploadFileData()
{
    m_pTimer->stop();//先关了,要不然他会重新计时
    QFile file(m_strUploadFilePath);
    if(!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(this,"上传文件", "打开文件失败");
        return;
    }
    
    char *pBuffer = new char[4096];
    qint64 ret =0;
    while (true) {
        ret = file.read(pBuffer,4096);
        if(ret>0&&ret<=4096)
        {
            //读到了数据
            TcpClient::getinstance().getTcpSocket().write(pBuffer,ret);
        }
        else if(0==ret){//数据已经读到了末尾了
            break;
        }
        else {
            QMessageBox::warning(this, "上传文件", "上传文件失败,读文件失败");
            break;
        }
    }
    file.close();
    delete [] (pBuffer);
    pBuffer=NULL;
}
void Book::uploadFile()
{
    //当前路径
    QString strCurPath = TcpClient::getinstance().curPath();
    //选择上传文件
    //QFileDialog::getOpenFileName();会弹出一个窗口来,类似于打开文件
    m_strUploadFilePath = QFileDialog::getOpenFileName();
    //qDebug()<<strUploadFilePath;
    //将名字提取出来
    if(!m_strUploadFilePath.isEmpty())
    {
        // aa/bb/cc 5 8
        int index = m_strUploadFilePath.lastIndexOf('/');
        QString strFileName =m_strUploadFilePath.right(m_strUploadFilePath.size()-index-1);
        //qDebug()<<strFileName;
        //将数据封装到PDU里面
        QFile file(m_strUploadFilePath);
        qint64 filesize = file.size();//获得文件大小
        PDU *pdu =mkPDU(strCurPath.size()+1);
        pdu->uiMsgType=ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST;
        memcpy(pdu->caMsg, strCurPath.toStdString().c_str(),strCurPath.size());
        //"%s %lld" %s文件名 lld文件大小long long 64
        sprintf(pdu->caData,"%s %lld", strFileName.toStdString().c_str(),filesize);
        //发送
        //发送给服务器
        TcpClient::getinstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
        free(pdu);
        pdu=NULL;
        
        //添加一个定时器防止数据粘连
        m_pTimer->start(1000);
        
    }
    else {
        QMessageBox::warning(this, "上传文件","上传文件名字不能为空!");
    }
}

2.11、打开服务器,接收上传文件内容

        //接收数据
        PDU *respdu = NULL;
        respdu =mkPDU(0);
        respdu->uiMsgType = ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND;
        QByteArray buff = readAll();//接收读到的数据
        m_file.write(buff);//将读到的数据写道buff里面去
        m_iReceived+=buff.size();
        if(m_iTotal==m_iReceived)
        {//接收数据结束了
            m_file.close();
            m_bUpload = false;
            strcpy(respdu->caData,UPLOAD_FILE_OK);
            //发送给客户端
            write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu =NULL;
        }
        else if ((m_iTotal<m_iReceived))
        {
            m_file.close();
            m_bUpload = false;
            strcpy(respdu->caData,UPLOAD_FILE_FAILED);
            //发送给客户端
            write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu =NULL;
        }
    }
}

2.12、客户端处理

        //---------------------上传文件------------------------
    case ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND:
    {        
        QMessageBox::information(this,"进入文件夹",pdu->caData);
        break;
    }  

3、测试

A、点击上传文件,选择文件并打开

 B、提示上传成功

C、发现jack文件夹里面也有了makefile文件

D、大的文件也可以上传

成功!!!!!!!!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1632197.html

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

相关文章

17.IIC原理及应用

IIC总线的一些特征 • 只要求两条总线线路 一条串行数据线 SDA 一条串行时钟线 SCL • 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机 从机关系软件设定地 址 主机可以作为主机发送器或主机接收器 • 它是一个真正的多主机总线 如果两个或更多主机同时初始…

sql今天学习总结

排序order by&#xff08;默认升序&#xff09; order by id desc(降序排序&#xff09; order by id,number&#xff08;先按id排再按name排序&#xff09; in,not in and or 通配符 where name like "Aa%";选取所有以Aa开头的名字 like "%r" 以r结…

CANoe如何实现TLS协议

TLS&#xff0c;Transport Layer Security&#xff0c;传输层安全协议。是在传输层和应用层之间&#xff0c;为了保证应用层数据能够安全可靠地通过传输层传输且不会泄露的安全防护。 TLS安全协议的实现逻辑&#xff0c;在作者本人看来&#xff0c;大致分为三个部分&#xff1…

Shell脚本入门:编写自动化任务的利器

一、Shell概述 Shell最早产生于20世纪70年代早期的Unix操作系统中。作为一种命令解释器&#xff0c;它位于操作系统的最外层&#xff0c;负责直接与用户进行交互。Shell把用户的输入解释给操作系统&#xff0c;并处理操作系统的输出结果&#xff0c;然后将其反馈给用户。这种交…

Windows当前无法访问>SmartScreen(安装程序长时间等待)的处理方法

问题描述&#xff1a;Windows下点击安装程序后&#xff0c;安装程序进入长时间等待状态&#xff08;估计有5分钟以上&#xff09;&#xff0c;等待过后弹出“当前无法访问>SmartScreen”提示窗口&#xff0c;提示窗口截图如下&#xff1a; 问题原因&#xff1a;系统开启了Mi…

Elasticsearch实现hotel索引库自动补全、拼音搜索功能

Elasticsearch实现hotel索引库自动补全、拼音搜索功能 在这里边我们有两个字段需要用拼音分词器&#xff0c;一个name字段&#xff0c;一个all字段。 然后我们还需要去实现自动补全&#xff0c;而自动补全对应的字段必须使用completion类型。目前我们酒店里面所有的字段都采用的…

MacPro(M1,M2芯片)Java开发和常用工具开源软件合集

目录 Java开发软件1 IDE1.1 idea1.2 Vs Code 2 开发工具2.1 数据库数据库模型管理数据库连接客户端 2.2 SSH/Telnet/Serial/Shell/Sftp客户端2.3 MarkDown编辑器2.3 代码片段管理粘贴 3小工具3.1 截图贴图3.2 Mac下修改hosts文件的图形化界面软件 Java开发软件 1 IDE 1.1 ide…

ElasticSearch教程入门到精通——第五部分(基于ELK技术栈elasticsearch 7.x+8.x新特性)

ElasticSearch教程入门到精通——第五部分&#xff08;基于ELK技术栈elasticsearch 7.x8.x新特性&#xff09; 1. Elasticsearch集成1.1 框架集成-SpringData-整体介绍1.2 Spring Data Elasticsearch 介绍1.3 框架集成-SpringData-代码功能集成1.3.1 创建Maven项目1.3.2 修改po…

pytorch中的过拟合和欠拟合

基本概念 我们知道&#xff0c;所谓的神经网络其实就是一个复杂的非线性函数&#xff0c;网络越深&#xff0c;这个函数就越复杂&#xff0c;相应的表达能力也就越强&#xff0c;神经网络的训练则是一个拟合的过程。   当模型的复杂度小于真实数据的复杂度&#xff0c;模型表…

linux中通过logrotate进行日志切割

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

Android 设置头像 - 裁剪及圆形头像

书接上文 Android 设置头像 - 相册拍照&#xff0c;通过相册和照片的设置就可以获取到需要的头像信息&#xff0c;但是在通常情况下&#xff0c;我们还想要实现针对头像的裁剪功能和圆形头像功能。 先上截图&#xff1a; 图像裁剪 通常裁剪可以分为程序自动裁剪和用户选择裁剪…

自适应信号处理基础及应用——DSP学习笔记五

本专栏的图片内容都来自于老师讲课的PPT&#xff0c;本篇博客只是我个人对于上课内容的知识结构分析和梳理。 导论 自适应系统的定义、特征、形式、举例 特征 非自适应系统 • 固定参数的设计方法 • 假定事先知道了一切可能的输入条件&#xff1b;在这些条件下怎样动作&#…

限流--4种经典限流算法讲解--单机限流和分布式限流的实现

为什么需要限流 系统的维护使用是需要成本的&#xff0c;用户可能使用科技疯狂刷量&#xff0c;消耗系统资源&#xff0c;出现额外的经济开销问题&#xff1a; 控制成本>限制用户的调用次数用户在短时间内疯狂使用&#xff0c;导致服务器资源被占满&#xff0c;其他用户无…

大象机器人开源六轴协作机械臂myCobot 320 手机摄影技术!

引言 有没有遇到过这样的情况&#xff1a;当你手持手机或相机准备拍摄视频时&#xff0c;心中已经构想了完美的画面&#xff0c;但却因为实际的限制无法捕捉到理想中的角度&#xff1f;这种情况可能会让人感到挫折。例如&#xff0c;如果想要从地面一只蚂蚁的视角拍摄&#xff…

dremio数据湖sql行列转换及转置

1、行转列 (扁平化) 数据准备 表 aa 1.1 cross join unnest 在Dremio中&#xff0c;UNNEST 函数用于将数组或复杂类型的列&#xff08;如JSON、Map或Array类型&#xff09;中的值“炸裂”&#xff08;分解&#xff09;成多行. with aa as ( select 上海 as city, ARRAY[浦东…

asp.net结课作业中遇到的问题解决1

作业要求 实现增删改查导出基本功能。 1、如何设置使得某个背景就是一整个而不是无限填充或者是这个图片的某一部分。 这就要求在设置这一块的时候&#xff0c;长和宽按照背景图片的大小进行设置&#xff0c;比如&#xff1a; 如果&#xff0c;图片的大小不符合你的要求&am…

技术团队的管理方法和日常总结建议

管理学家德鲁克有言“管理是一种实践&#xff0c;其本质不在于知&#xff0c;而在于行&#xff0c;其验证不在于逻辑&#xff0c;而在于成果&#xff0c;其唯一的权威就是成就” &#xff0c;因此管理重实践看效果&#xff0c;但如果管理实践有理论依凭&#xff0c;那么实践起来…

云手机对出海企业有什么帮助?

近些年&#xff0c;越来越多的企业开始向海外拓展&#xff0c;意图发掘更广阔的市场。在这过程中&#xff0c;云手机作为一个新型工具为很多企业提供了助力&#xff0c;尤其在解决海外市场拓展过程中的诸多挑战方面发挥着作用。 首先&#xff0c;云手机的出现解决了企业在海外拓…

VS2022 嘿嘿

还是大二的时候就开始用这个&#xff0c;但居然是为了用PB&#xff0c;-_-|| 用了段时间换成了C#&#xff0c;依稀还记得大佬们纠正我的读法&#xff0c;别读C井&#xff0c;应该读C夏普。。。 安装过程其实也没啥&#xff0c;就是关键Key得花时间找&#xff0c;我好不容易搞…

Android如何使用XML自定义属性

1、定义 在res/values文件下定义一个attrs.xml文件&#xff0c;代码如下: 2、使用 在布局中使用&#xff0c; 示例代码如下&#xff1a; 3、获取 最终来到这里&#xff1a;