请问怎么停止一个正在工作的idhttp。并且能够让他继续重新开始下载。在线等待。

cdsun 2006-04-10 04:01:06
IDHTTP:= TIDHTTP.Create(nil);
MyStream:=TMemoryStream.Create;

try
form1.idhttp1.Connect();
except
end;

if form1.idhttp1.Connected then
begin
try

form1.IdHTTP1.Get('http://dl_dir.qq.com/qqfile/qq2006beta1.exe',MyStream);

filepath:=ExtractFilePath(ParamStr(0));

MyStream.SaveToFile(filepath+'\DownLoadFiles\11.exe');
MyStream.Free;

showmessage('下载完成!');
except

showmessage('网络出错未能下载完成!');
MyStream.Free;
Exit;
end;


这是我现在能够成功下载的代码

请大家多指点,希望能给一些源码

顺便问问怎么能够得到正在下载的文件相关信息,如总大小、下载速度等

在onwork的时候可以得到但是我用一个全局变量获得之后好像不能在其他地方用。

请各位兄弟们都来参与讨论
...全文
505 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
cdsun 2006-04-13
  • 打赏
  • 举报
回复
怎么就是没有人回答我的问题啊

我日哦
Randomize 2006-04-12
  • 打赏
  • 举报
回复
HTTP协议的:
procedure TForm1.HttpDownLoad(aURL, afile: string; bResume:Boolean);
var
tStream: TFileStream;
begin //Http方式下载
if FileExists(aFile) then //如果文件已经存在
tStream := TFileStream.Create(aFile, fmOpenWrite)
else
tStream := TFileStream.Create(aFile, fmCreate);
if bResume then //续传方式
begin
IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;
tStream.Position := tStream.Size - 1; //移动到最后继续下载
IdHTTP1.Head(aURL);
IdHTTP1.Request.ContentRangeEnd :=
IdHTTP1.Response.ContentLength;
end else //覆盖或新建方式
begin
IdHTTP1.Request.ContentRangeStart := 0;
end;
try
IdHTTP1.Get(aURL, tStream); //开始下载
finally
tStream.Free;
end;
end;

这里我们同样使用IdHTTP的Get过程,函数的aURL是网址,aFile是保存的文件名,bResume确定是否续传,需要注意的就是续传方式时的代码:
IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;
tStream.Position := tStream.Size - 1; //移动到最后继续下载
IdHTTP1.Head(aURL);
IdHTTP1.Request.ContentRangeEnd :=
IdHTTP1.Response.ContentLength;
第一行我们将下载开始位置设置为读入文件流的末尾,也就是设置为已经下载了的那部分文件的大小,第二行我们将文件流本身也指向自己的末尾,第三行我们通过Head过程得到网址头信息,在第四行将头信息的文件总大小赋值给下载的结束的位置,至于这里为什么第一行和第二行代码最后都要-1,我当时没有加-1的时候在续下载一个完整的已经下载的文件的时候总是提示错误,最后跟踪IdHTTP的代码发现他在处理下载范围的时候如果开始的位置和结束位置一样时会引发将浮点数转为整数的错误,因而这里加上-1防止这种错误发生,另外一种处理方法就是比较如果开始位置等于结束位置就退出也是可以的。
再来看FTP协议的下载过程:
procedure TForm1.FtpDownLoad(aURL, afile: string; bResume: Boolean);
var
tStream: TFileStream;
sName, sPass, sHost, sPort, sDir: string;
begin //ftp方式下载
if FileExists(aFile) then //建立文件流
tStream := TFileStream.Create(aFile, fmOpenWrite) else
tStream := TFileStream.Create(aFile, fmCreate);
GetFTPParams(aURL, sName, sPass, sHost, sPort, sDir);
with IdFTP1 do
try
if Connected then Disconnect; //重新连接
Username := sName;
Password := sPass;
Host := sHost;
Port := StrToInt(sPort);
Connect;
except
exit;
end;
IdFTP1.ChangeDir(sDir); //改变目录
BytesToTransfer := IdFTP1.Size(aFile);
try
if bResume then //续传
begin
tStream.Position := tStream.Size;
IdFTP1.Get(aFile, tStream, True);
end else
begin
IdFTP1.Get(aFile, tStream, False);
end;
finally
tStream.Free;
end;
end;
这个过程中我们就用到了GetFTPParams()函数将网址的用户名、密码、主机地址、端口、路径等信息分离出来,IdFTP利用这些信息登陆服务器并到相应目录,最后利用Get()过程就很容易实现下载了,它的续传就比HTTP协议要简单很多,因为IdFTP的Get()本身就支持续传。
这里我简单穿插一点的内容,一个服务器是否支持断点续传,我们可以通过发送REST 1FTP指令来检测,如果返回350则表示支持。
最后我们根据网址来确定使用什么协议来下载:
function TForm1.GetProt(aURL: string): Byte;
begin //检测下载的地址是http还是ftp
Result := 0;
if Pos('http', LowerCase(aURL)) = 1 then
Result := 1; //http协议
if Pos('ftp', LowerCase(aURL)) = 1 then
Result := 2; //ftp协议
end;
这个函数根据网址返回整数供我们使用。
procedure TForm1.MyDownLoad(aURL, afile: string; bResume: Boolean);
begin
case GetProt(aURL) of
0: ShowMessage('不可识别的地址!');
1: HttpDownLoad(aURL, aFile, bResume);
2: FtpDownLoad(aURL, aFile, bResume);
end;
end;
这个过程就利用GetProt()函数返回的整数执行相应的协议下载过程。
接下来看看每个按钮的代码,有了上面的函数,按钮的代码就简单多了:
下载按钮:
procedure TForm1.Button1Click(Sender: TObject);
var
aURL, afile: string;
begin
aURL := ComboBox1.Text; //下载地址
aFile := GetURLFileName(aURL); //得到文件名,例如demo.exe
if FileExists(aFile) then
begin
case MessageDlg('文件已经存在,是否续传?', mtConfirmation, mbYesNoCancel,0) of
mrYes: MyDownLoad(aURL, aFile, True); //续传
mrNo: MyDownLoad(aURL, aFile, False); //覆盖
mrCancel: Exit; //取消
end;
end else MyDownLoad(aURL, aFile, False); //建立新文件下载
end;
MessageDlg()函数弹出一个对话框让用户选择续传、覆盖还是取消下载。
中断按钮:
procedure TForm1.Button2Click(Sender: TObject);
begin
AbortTransfer := True;
end;
前面忘了介绍,所以这里大家看不明白,AbortTransfer是我们定义的一个私有变量,在开始下载的时候将它设为False,下载的过程中随时监测这个变量,一旦变为True就利用IdHTTP的Disconnect和IdFTP1的Abort方法中断下载,如果没有下载完就中断,那程序的目录中就会有一个下载不完整的程序或者其他东西,下次再下载的时候我们就可以选择续传来完成剩下的下载过程。
procedure TForm1.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer);
begin
AbortTransfer := False;
……
end;
在IdHTTP1和IdFTP的OnWorkBegin事件我们就将AbortTransfer设置为False了,在他们的Work事件中,我们检测AbortTransfer变量来完成是否中断的操作。
procedure TForm1.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;const AWorkCount: Integer);
begin
if AbortTransfer then
begin //中断下载
IdHTTP1.Disconnect;
IdFTP1.Abort;
end;
ProgressBar1.Position := AWorkCount;
Application.ProcessMessages;
end;
最后是连接状态等信息的代码:
在IdHTTP和IdFTP的OnStatus事件写入:
procedure TForm1.IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;const AStatusText: string);
begin
ListBox1.ItemIndex := ListBox1.Items.Add(AStatusText);
end;
因为IdHTTP和IdFTP在OnWork、OnStatus等事件上执行的代码都是一样的,所以我们只用写其中一个的代码,然后另外一个选择相同的事件就OK了。

ZT
cdsun 2006-04-12
  • 打赏
  • 举报
回复
怎么停止呢?

还没停止没办法测试断点续传
cdsun 2006-04-11
  • 打赏
  • 举报
回复
csdn没有人了吗?
cdsun 2006-04-10
  • 打赏
  • 举报
回复
为什么我的问题每次都没人理我
cdsun 2006-04-10
  • 打赏
  • 举报
回复
procedure TMyDownLoad.Download;
Var
UnitName,PathName:String;
MyStream:TMemoryStream;
filepath:string;
IDHTTP: TIDHttp;

begin
//form1.IDHTTP:= TIDHTTP.Create(nil);
//form1.StatusBar1.Panels[0].Text:='正在下载文件...';
IDHTTP:= TIDHTTP.Create(nil);
MyStream:=TMemoryStream.Create;

try
form1.idhttp1.Connect();
except
end;

if form1.idhttp1.Connected then
begin
try
form1.IdHTTP1.Get('http://dl_dir.qq.com/qqfile/qq2006beta1.exe',MyStream);
filepath:=ExtractFilePath(ParamStr(0));

MyStream.SaveToFile(filepath+'\DownLoadFiles\11.exe');
MyStream.Free;
showmessage('下载完成!');
except
showmessage('网络出错未能下载完成!');
MyStream.Free;
Exit;
end;

end;
end;

constructor TMyDownLoad.Create();
begin

FreeOnTerminate := True; // 自动删除
InitializeCriticalSection(CS); //初始化临界区
inherited Create(False); // 直接运行
end;




procedure TMyDownLoad.Execute;
begin
{ Place thread code here }
EnterCriticalSection(cs); //进入临界区
if Terminated then exit;
Synchronize(Download);
LeaveCriticalSection(CS); //退出临界区
end;



这里是我线程工作的主要代码,请问该如何动态添加。可以用一个按钮模拟

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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