关于下载线程暂停之后如何继续下载的问题?

yiruirui0507 2012-03-13 06:27:13
一个线程下载某个URL上的文件,设置了暂停下载,继续下载,取消下载三个按钮。当暂停下载的时候挂起线程,当继续下载的时候如何继续下载呢?也就是续传问题吧。
下载线程函数:

UINT _cdecl CMyDialog::DownloadFile(LPVOID pParam)
{
//把this指针传进来
CMyDialog *pDlg=(CMyDialog*)pParam;
CProgressCtrl *m_Prog=(CProgressCtrl*)pDlg->GetDlgItem(IDC_PROGRESS1);
CButton *bStart=(CButton*)pDlg->GetDlgItem(IDC_SOFT_DOWN);
char filebuf[512];
CInternetSession netSession;
CStdioFile *fTargFile;
int outfs;
CString szFile,FileSize,KBin,KBsec,NewName,Perc;
try
{
szFile=pDlg->m_strDown;
pDlg->SetDlgItemText(IDC_STAT,_T("正在校验下载地址..."));
fTargFile=netSession.OpenURL(szFile,1,INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_RELOAD);
pDlg->nDownloaded=1;

COleDateTime dlStart=COleDateTime::GetCurrentTime();
int filesize=fTargFile->SeekToEnd();
fTargFile->Seek(pDlg->nRecord,CFile::begin);
// fTargFile->SeekToBegin();
outfs=filesize/1024;// 计算文件大小(千字节)
FileSize.Format(_T("%d"),outfs);// 以KB为单位格式文件大小

// 在当前目录创建新的目标文件
CFile fDestFile(fTargFile->GetFileName(),CFile::modeCreate|CFile::modeWrite|CFile::typeBinary|CFile::modeNoTruncate);
int byteswrite;// 写入文件的字节数
// pDlg->pos=0;// 当前进度条的位置
int nperc,kbrecv;// 进度条的百分比,获取到的数据大小(Kbs为单位)
double secs,kbsec;// 记录秒数, 速度(KB/秒)

// 如果文件名太长,缩短窗口的标题并在状态显示
NewName=fTargFile->GetFileName();// 获取新文件名
if(fTargFile->GetFileName().GetLength()>=10)
{
NewName=fTargFile->GetFileName().Mid(0,7);// 分割文件
NewName=NewName+_T("...");
}
pDlg->SetDlgItemText(IDC_STAT,_T("正在下载..."));
m_Prog->SetRange32(0,filesize);
while(byteswrite=fTargFile->Read(filebuf,512))// 读取文件
{
if(pDlg->nTerminate==1)// 如果点击取消下载
{
//下载取消之后要更新pDlg->nDownloaded的值为初始值
pDlg->nDownloaded=0;
fDestFile.Close(); // 关闭我们的目标文件
fTargFile->Close(); // 关闭远程文件
delete fTargFile;// 删除CStdioFile对象,以防止泄漏
pDlg->SetDlgItemText(IDC_STAT,_T("下载已被用户取消!"));
AfxEndThread(0);// 结束下载线程
}
// 根据开始时间与当前时间比较,获取秒数
COleDateTimeSpan dlElapsed=COleDateTime::GetCurrentTime()-dlStart;
secs=dlElapsed.GetTotalSeconds();
pDlg->pos=pDlg->pos+byteswrite;// 设置新的进度条位置
fDestFile.Write(filebuf,byteswrite);// 将实际数据写入文件
m_Prog->SetPos(pDlg->pos);
nperc=pDlg->pos*100/filesize;// 进度百分比
kbrecv=pDlg->pos/1024;// 获取收到的数据
kbsec=kbrecv/secs;// 获取每秒下载多少(KB)
Perc.Format(_T("%d"),nperc); // 格式化进度百分比
KBin.Format(_T("%d"),kbrecv);// 格式化下载速度(KB/秒)
KBsec.Format(_T("%d"),(int)kbsec);
pDlg->SetDlgItemText(IDC_DOWNRATE,KBsec+"KB/秒");
pDlg->SetDlgItemText(IDC_DOWNPERCENT,Perc+"%");
pDlg->nRecord+=512;
Sleep(1);//Missnow
}
fDestFile.Close();// 下载完成,关闭文件
}
catch(CInternetException *IE)
{
CString strerror;
TCHAR error[255];
IE->GetErrorMessage(error,255);// 获取错误消息
// if(IE->m_dwError==ERROR_INTERNET_OPERATION_CANCELLED)
// AfxMessageBox(_T("无效下载地址!"));
strerror=error;
pDlg->SetDlgItemText(IDC_STAT,strerror);
pDlg->nDownloaded=0;
delete fTargFile;
IE->Delete(); // 删除异常对象,以防止泄漏
return 0;
}
pDlg->SetDlgItemText(IDC_DOWNRATE,_T("Kb/秒"));
pDlg->SetDlgItemText(IDC_DOWNPERCENT,_T("100%"));
delete fTargFile;
if(pDlg->nDownloaded==1)
{
pDlg->SetDlgItemText(IDC_STAT,_T("下载完成!"));
bStart->SetWindowText(_T("打开目录"));
::ShowWindow(::GetDlgItem(pDlg->m_hWnd,IDC_SUSPEND_DOWN),SW_HIDE);
//隐藏
//下载完毕后重新归位初始值
pDlg->nDownloaded=0;
bStart->EnableWindow(TRUE);
}
return 0;
}


线程创建函数
CWinThread *pThread=AfxBeginThread(DownloadFile,(LPVOID)this,THREAD_PRIORITY_NORMAL);

public:
int pos;//记录进度条的位置
LONGLONG nRecord;//记录下载的字节数
HANDLE m_hThread;//记录下载线程句柄

初始化:
	m_hThread    =NULL;
nRecord =0;//记录文件下载byte数量
pos =0;//进度条初始位置

思路好像没问题吧:
循环每次下载固定字节内容,然后用成员变量nRecrod来记录,下次线程启动的时候直接fTargFile->Seek(pDlg->nRecord,CFile::begin);定位文件指针到某处,然后继续下载。

但是运行:点击按钮进行继续下载的时候不对,请问是哪里出了问题?
...全文
355 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zlm8715 2012-03-14
  • 打赏
  • 举报
回复
不知道你这个暂停是怎么处理的,像你在群里说的用WaitForSignalObject()这个可能不太好,应该有挂起线程,启动线程的函数的,SuspendThread(), ResumeThread();
yiruirui0507 2012-03-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhaoze87 的回复:]
你暂停的时候只是挂起了线程,继续下载不过是重新唤醒这个线程而已,不存在续传的问题
[/Quote]
重新唤醒了线程继续下载,从上次记录的地方继续下载不算是续传吗?
小马喝水 2012-03-14
  • 打赏
  • 举报
回复
你暂停的时候只是挂起了线程,继续下载不过是重新唤醒这个线程而已,不存在续传的问题
zlm8715 2012-03-14
  • 打赏
  • 举报
回复
byteswrite=fTargFile->Read(filebuf,512) 这里返回了实际读取的长度byteswrite,
但是你记录的长度是pDlg->nRecord+=512; byteswrite有可能不等于512吧,这个不知道有没有影响呢。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧