文件的分段传输 我做了一个关于文件传输的程序,但是只能传送几十兆以内的小型文件,我想通过文件分段传输实现大型文件的传输,希望大家帮帮忙!先谢了。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 找出“只能传送几十兆以内”的原因。分包,其实就是一次从文件当中读一块(由于网络的速度是有限的,所以没有任何必要把整个文件几十几百兆一次性读入内存,这个内存消耗是非必要的),然后发送,再读一块。一般只要保留文件的句柄就不需要作任何动作,直接readfile就可以(读文件的时候也不可能是你想读多少就一定能给你读取出来的,而是通过返回值告诉你读取了多少,此时你可能需要继续读取,而你也可以先把读完的发送了,再继续读取。另外文件也可以通过seek或者SetFilePointer设置文件指针,于是你就可以在任意时间里进行选择性地发送某一段或某几段。 简单点的方式,用TCP协议建立连接,打开文件,做一个循环,每次读一小段数据,发送出去,再循环。 我对文件分段了,代码如下,在程序运行的时候只能打开4096k以下的文件(我把文件分成4096一块)。 length=strlen(sFname); //获取文件名长度 //发送文件名长度 sendmessage(csock,(const char*)&length,sizeof(int)); //发送文件名 sendmessage(csock,sFname,length); file.open(filename,ios::binary); //用二进制打开文件 if(file.fail()) { MessageBox("文件打开失败!"); goto EXIT; } fb=file.rdbuf(); length=fb->seekoff(0,ios::end,ios::in)-fb->seekoff(0,ios::beg,ios::in); fb->seekoff(0,ios::beg,ios::in); //获取文件长度 //发送文件大小 sendmessage(csock,(const char*)&length,sizeof(int)); bRet=TRUE; char data[4097]; while(length>0) { int len=0; if(length <= 4096) { len = length; } else { len = 4096; } //准备缓冲区// data=new char[len]; file.read(data,len);// data[length] = '\0'; //发送整个文件 bRet=sendmessage(csock, data, len); length -= len;// delete[] data; } file.close(); if(bRet){// MessageBox("发送成功!"); } else{ MessageBox("发送失败!"); }希望大家不吝指教。谢谢! 你能帮我改一改吗,或用API帮我写一个,谢谢 。 API可以查MSDNCreateFile打开文件SetFilePointer(相当于seekoff)ReadFile读文件CloseHandle关闭文件句柄。 我在做文件操作时一般都是用API的,不过CFile应该也没问题,你是open的时候返回false吗? 文件open的时候没有返回false,只是卡住不动了。 file.open(filename,ios::binary); 确定路径正确,除了2进制,带必要的读写参数 看看思路了,呵呵!NGCMDHEADER header; status stsCode = statusOk; FILE* fp = NULL; // Open file fp = fopen(strFileName.c_str(), "rb"); if (fp == NULL) { return statusCreateFileError; } // char szDataBuf[MAX_DATABUF_LEN]; size_t dwItem = 0; // header.dwCmd = CMD_FDDATA; // Send file data while (true) { dwItem = fread(szDataBuf, sizeof(char), MAX_DATABUF_LEN, fp); header.dwBufLen = dwItem; stsCode = socket.SendExact((char*)&header, sizeof(header)); if (stsCode != statusOk) { break; } stsCode = socket.SendExact(szDataBuf, dwItem); if (stsCode != statusOk) { break; } if (dwItem < MAX_DATABUF_LEN) { header.dwCmd = CMD_FDEND; header.dwBufLen = 0; stsCode = socket.SendExact((char*)&header, sizeof(header)); LogFileTransferInfo(LOG_FILE, strFileName, ts.nCurFileTransferedSize); break; } // update information ts.nCurFileTransferedSize += header.dwBufLen; SendMessage(GetMsgProcHwnd(), WM_TASK_STATUS_UPDATE, STATUS_UPDATE_FILE, (LPARAM)&ts); } // Close file & socket fclose(fp); char Ext[6]; char szFileName[MAX_PATH]; strcpy(szFileName,strFileName.c_str()); _GetFileExtName(szFileName,Ext); if( strcmp(Ext,".NSOFT") ==0 ) { ::DeleteFile(szFileName); } return stsCode;} List Control 插入图片后,选中状态,图片消失了,变成空白。 局域网问题? MFC对话框工程里有个成员变量是某个类的对象的指针,请问在哪里new比较好呢?又在哪delete呀? 我有一个VC++6.0程序,在本机运行好的,到别的机子运行界面出不来? VC++安装问题 请问VC6.0有没有纯中文版的,而非汉化版的。 没发现CADORecordBinding类 用电脑扫描二维码怎么做啊 初学者向各位高手招教几招 程序跟换计算机后重连SQL Sever数据库 wlan wpa(wep)验证 请问SAFEARRAY该怎么用?
length=strlen(sFname); //获取文件名长度
//发送文件名长度
sendmessage(csock,(const char*)&length,sizeof(int));
//发送文件名
sendmessage(csock,sFname,length);
file.open(filename,ios::binary); //用二进制打开文件
if(file.fail())
{
MessageBox("文件打开失败!");
goto EXIT;
}
fb=file.rdbuf();
length=fb->seekoff(0,ios::end,ios::in)-fb->seekoff(0,ios::beg,ios::in);
fb->seekoff(0,ios::beg,ios::in); //获取文件长度
//发送文件大小
sendmessage(csock,(const char*)&length,sizeof(int));
bRet=TRUE;
char data[4097];
while(length>0)
{
int len=0;
if(length <= 4096)
{
len = length;
}
else
{
len = 4096;
}
//准备缓冲区
// data=new char[len];
file.read(data,len);
// data[length] = '\0';
//发送整个文件
bRet=sendmessage(csock, data, len);
length -= len;
// delete[] data;
} file.close();
if(bRet){
// MessageBox("发送成功!");
}
else{
MessageBox("发送失败!");
}
希望大家不吝指教。谢谢!
CreateFile打开文件
SetFilePointer(相当于seekoff)
ReadFile读文件
CloseHandle关闭文件句柄。
NGCMDHEADER header;
status stsCode = statusOk;
FILE* fp = NULL;
// Open file
fp = fopen(strFileName.c_str(), "rb");
if (fp == NULL)
{
return statusCreateFileError;
}
//
char szDataBuf[MAX_DATABUF_LEN];
size_t dwItem = 0;
//
header.dwCmd = CMD_FDDATA;
// Send file data
while (true)
{
dwItem = fread(szDataBuf, sizeof(char), MAX_DATABUF_LEN, fp);
header.dwBufLen = dwItem;
stsCode = socket.SendExact((char*)&header, sizeof(header));
if (stsCode != statusOk)
{
break;
}
stsCode = socket.SendExact(szDataBuf, dwItem);
if (stsCode != statusOk)
{
break;
}
if (dwItem < MAX_DATABUF_LEN)
{
header.dwCmd = CMD_FDEND;
header.dwBufLen = 0;
stsCode = socket.SendExact((char*)&header, sizeof(header));
LogFileTransferInfo(LOG_FILE, strFileName, ts.nCurFileTransferedSize);
break;
}
// update information
ts.nCurFileTransferedSize += header.dwBufLen;
SendMessage(GetMsgProcHwnd(), WM_TASK_STATUS_UPDATE, STATUS_UPDATE_FILE, (LPARAM)&ts);
}
// Close file & socket
fclose(fp); char Ext[6];
char szFileName[MAX_PATH];
strcpy(szFileName,strFileName.c_str());
_GetFileExtName(szFileName,Ext);
if( strcmp(Ext,".NSOFT") ==0 )
{
::DeleteFile(szFileName);
} return stsCode;
}