写了段demo,其实如果下载了indy,它是自带有demo 的,这里用到了线程和地址重定向,算是一个简单的实例吧,由于时间仓促,封装和命名上就马虎了。注析也不详细。 下载文件是http://www.bc-cn.net/Soft/kfyy/delphi/edu/200604/296.html 界面部分:
Unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Unit2, ComCtrls, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Button1: TButton; ProgressBar1: TProgressBar; Button2: TButton; Button3: TButton; Memo1: TMemo; Button4: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } fWeb: string; fDownLoadThread: TDownLoadThread; public { Public declarations } procedure OnShowProgress(DownCount: Integer); procedure OnGetFileSize(fileSize: Integer); procedure OnShowStatus(aString: string); end;
var Form1: TForm1;
implementation
{$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin fDownLoadThread := TDownLoadThread.Create(True); fDownLoadThread.FreeOnTerminate := True; fDownLoadThread.OnDownLoadCount := OnShowProgress; fDownLoadThread.OnShowString := OnShowStatus; fDownLoadThread.OnGetFileSize := OnGetFileSize; fDownLoadThread.initDownLoad(fWeb); fDownLoadThread.Resume(); end;
procedure TForm1.OnShowProgress(DownCount: Integer); begin if DownCount > ProgressBar1.Max then Exit else ProgressBar1.Position := DownCount; end;
procedure TForm1.OnGetFileSize(fileSize: Integer); begin ProgressBar1.Position := 0; ProgressBar1.Max := fileSize; end;
procedure TForm1.Button2Click(Sender: TObject); begin fDownLoadThread.Terminate(); end;
procedure TForm1.Button3Click(Sender: TObject); begin fDownLoadThread.Suspend(); end;
procedure TForm1.OnShowStatus(aString: string); begin Memo1.Lines.Add(aString); end;
procedure TForm1.FormShow(Sender: TObject); begin // 页面是 http://www.bc-cn.net/Soft/kfyy/delphi/edu/200604/296.html fWeb := 'http://www.bc-cn.net/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296'; Edit1.Text := '目标地址:' + fWeb; end;
end.
下载线程部分
unit Unit2;
interface
uses Classes, SysUtils, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdFTP;
type TOnDownLoadCount = procedure(DownCount: Integer) of object; TOnShowString = procedure(aString: string) of object; TDownLoadThread = class(TThread) private { Private declarations } fDestFileName: string; fFileSize: Integer; FDestWebAddr: string; fIdHttp: TIdHTTP; fIdFtp: TIdFTP; fDownLoadItem: TFileStream; fOnDownLoadCount: TOnDownLoadCount; fOnShowString: TOnShowString; fOnGetFileSize: TOnDownLoadCount; procedure OnDownLoadWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); procedure OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); procedure OnStatus(axSender: TObject; const axStatus: TIdStatus; const asStatusText: String); procedure OnRedirect(Sender: TObject; var dest: String; var NumRedirect: Integer; var Handled: Boolean); protected procedure Execute; override; public constructor Create(CreateSuspended: Boolean); destructor Destroy(); override; procedure initDownLoad(aWeb: string); property OnDownLoadCount: TOnDownLoadCount write fOnDownLoadCount; property OnShowString: TOnShowString write fOnShowString; property OnGetFileSize: TOnDownLoadCount write fOnGetFileSize; end;
implementation { TDownLoadThread }
procedure TDownLoadThread.Execute; begin { Place thread code here } try fIdHttp.Connect(); fIdHttp.Head('/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296'); except if FDestWebAddr <> '' then fOnShowString('地址重定向到:' + FDestWebAddr) else fOnShowString('连接失败.'); end;
// 这里这里应该分析重定向后的地址FDestWebAddr,根据地址决定是http下载还是ftp下载 这里省略了。 // 得到的地址是:ftp://down1:008@down1.bc-cn.net/down1_18/1_kfyy/5_delphi/edu/delphi7_zjjfbsyykf.rar // 分析地址应该使用ftp,并得到一下信息 fIdFtp := TIdFTP.Create(nil); fIdFtp.User := 'down1'; // 用户名 fIdFtp.Password := '008'; // 密码 fIdFtp.Host := 'down1.bc-cn.net'; // 主机 fIdFtp.Port := 21; // 端口,可以不设,默认就是21的 ,这里用的是端口模式。 fIdFtp.OnWork := Self.OnDownLoadWork; // 实现相应的事件,这是下载过程 fIdFtp.OnWorkBegin := Self.OnWorkBegin; // 下载开始 fIdFtp.OnStatus := Self.OnStatus; fIdFtp.Connect(); fFileSize := fIdFtp.Size('/down1_18/1_kfyy/5_delphi/edu/delphi7_zjjfbsyykf.rar'); fOnShowString('文件大小: ' + IntToStr(fFileSize)); fIdFtp.Get('/down1_18/1_kfyy/5_delphi/edu/delphi7_zjjfbsyykf.rar', fDownLoadItem); end;
procedure TDownLoadThread.OnDownLoadWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); begin if Self.Terminated then begin try TIdTCPConnection(Sender).DisconnectSocket(); except fOnShowString(' DisconnectSocket'); end; end; fOnDownLoadCount(AWorkCount); fOnShowString('目前下载量:' + IntToStr(AWorkCount)); end;
procedure TDownLoadThread.OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); begin if fFileSize <> 0 then fOnGetFileSize(fFileSize); end;
procedure TDownLoadThread.OnStatus(axSender: TObject; const axStatus: TIdStatus; const asStatusText: String); begin fOnShowString(asStatusText); end;
procedure TDownLoadThread.initDownLoad(aWeb: string); begin // 论坛的一个文件地址 //aWeb = http://www.bc-cn.net/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296 // 这里分析得到主机名为 www.bc-cn.net, 要下载的文件是/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296 // 这里省略了 fIdHttp.Host := 'www.bc-cn.net'; fIdHttp.Port := 80; fIdHttp.HandleRedirects := True; // 设置重定向 fIdHttp.OnRedirect := Self.OnRedirect; fIdHttp.OnStatus := Self.OnStatus; end;
constructor TDownLoadThread.Create(CreateSuspended: Boolean); begin fIdHttp := TIdHTTP.Create(nil); inherited Create(CreateSuspended); end;
destructor TDownLoadThread.Destroy(); begin fIdHttp.Free(); inherited Destroy(); end;
procedure TDownLoadThread.OnRedirect(Sender: TObject; var dest: String; var NumRedirect: Integer; var Handled: Boolean); var i: Integer; begin i := LastDelimiter('/', dest); FDestWebAddr := dest; fDestFileName := Copy(dest, i + 1, Length(dest)); fDownLoadItem := TFileStream.Create(fDestFileName, fmCreate); end;
end.
|