myfile.Close();//关闭辅助文件。
destFile.Close();//关闭目标文件。
delete [] m_buf;//删除用来从服务器端接收数据的缓冲区。
shutdown(m_socket,2);//关闭连接socket。
//The shutdown function does not close the socket. Any resources attached to the socket will not be freed until closesocket is invoked.
closesocket(m_socket);//added by yjk
//如果剩余的字节数<=0,则
if(remanent<=0)
good[index]=TRUE;//设为true,大概表示:文件的这一段已经被成功下载下来了。
return 1;
}
//开始下载用户选中的那个“可下载的文件”。
//参数是:要下载的文件的下标索引。
int cdownload::startask(int n)
{
//读入文件长度
doinfo.filelen=zmfile[n].length;
//读入文件名
m_fname=zmfile[n].name;
//给主窗体发消息
CString aaa;
aaa="正在读取 "+m_fname+" 信息,马上开始下载。。。\n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
aaa.ReleaseBuffer();
//如果文件长度小于0,则 返回-1
if(doinfo.filelen<=0)
return -1;
//建一个以.down结尾的文件,用来记录文件信息
CString csTemp;
csTemp=m_fname+".down";
//保存以.down结尾的文件之名。
doinfo.name=csTemp;
FILE* fp=NULL;
CFile myfile;
//Run-Time Library Reference fopen, _wfopen Open a file.
//The character string mode specifies the type of access requested for the file, as follows:
//"r" Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
//Return Value Each of these functions returns a pointer to the open file. A null pointer value indicates an error.
//如果以r的方式打开XX.down文件失败,则说明此文件不存在,从而说明这是第一次下载此文件,
//于是就:初使化对应于各个下载线程的辅助文件。
if((fp=fopen(csTemp,"r"))==NULL)
{
//added by yjk begin
//看看要下载的文件是否已经存在了,如果是已经存在了,就需要询问一下用户,是否要
//重新下载,如果用户选择重新下载,将删除原来的文件。
if((fp=fopen(m_fname,"r"))!=NULL)
{
fclose(fp);
//如果用户不想重新下载,就返回2,终止这次下载操作。
if(::MessageBox(NULL,"同名的文件已经存在了,如果选择“是”将覆盖原来的文件。你是否还要下载此文件?"," YJK 提醒用户",MB_YESNO|MB_ICONQUESTION)==IDNO)
return 2;
//删除原来的文件,这样,就跟以前从没有下载过此文件一样了。
DeleteFile(m_fname);
}
//added by yjk end
//这里已经把filerange[0]设定为0了,这表示,数组中的元素的值是从0开始的。
filerange[0]=0;
//文件分块
//BLOCK的值为4,那么就是从0至3进行循环了。假设文件的长度为203,那么
//“doinfo.filelen/BLOCK”就等于50了。
for(int i=0;i<BLOCK;i++)
{
if(i>0)
//当i==1的时候,filerange[2]=50;
//当i==2的时候,filerange[4]=100;
//当i==3的时候,filerange[6]=150;
// filerange[i*2]=i*(doinfo.filelen/BLOCK+1);//加上1,是为了防止程序在遇到doinfo.filelen/BLOCK==0这种情况的时候,运行出错。
filerange[i*2]=i*(doinfo.filelen/BLOCK);//added by yjk
//当i==0的时候,filerange[1]=50;
//当i==1的时候,filerange[3]=50;
//当i==2的时候,filerange[5]=50;
//当i==3的时候,filerange[7]=50;
// filerange[i*2+1]=doinfo.filelen/BLOCK+1;//
filerange[i*2+1]=doinfo.filelen/BLOCK;//added by yjk
}
//由filerange[4*2-1]=200-filerange[4*2-2]; 可得:filerange[7]=203-150,这等于是给
//filerange[7]赋了一个新值53(原值也是50)。之所以需要这最后的一句代码,是因为
//doinfo.filelen可能并不能被BLOCK完全除尽,所以,文件分段的时候,会有一些误差,所以,
//需要在最后的这一段中,修正这个误差。修正的方法很简单:就是前面的几段都分配完了
//之后,所剩下的字节数就是这最后一段的长度了。
//我认为,如果有了这最后的一句,那么,就完全可以不用加1了!当遇到
//doinfo.filelen/BLOCK==0这种情况的时候,前几个线程段的长度都是0,而最后一段的长度
//等于文件的实际的长度。
filerange[BLOCK*2-1]=doinfo.filelen-filerange[BLOCK*2-2];
//创建那个以.down结尾的辅助文件。
//CFile::modeCreate Directs the constructor to create a new file. If the file exists already, it is truncated to 0 length.
//CFile::modeWrite Opens the file for writing only.
myfile.Open(csTemp,CFile::modeCreate|CFile::modeWrite | CFile::typeBinary);
//将要下载的文件的“文件长度”写入这个以.d
上一篇:
CDoc_3View.cpp
下一篇:
产品定价因素分析MBA论文:以印度移动应用程序定价分析为例