本文主要讲解网盘里面关于文件操作部分的上传文件,具体步骤如下
目录
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、大的文件也可以上传
成功!!!!!!!!!!!