| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4478 人关注过本帖, 1 人收藏
标题:[开源][原创]关于自动更新的下载部分
只看楼主 加入收藏
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
结帖率:100%
收藏(1)
 问题点数:0 回复次数:5 
[开源][原创]关于自动更新的下载部分
*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: anthony634
*/ 时间: 2007-10-22 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------


上周有位本论坛的朋友在QQ里问到传奇私服的自动更新的问题,当时在网吧打游戏随便回答了一些问题,今天早上刚好有空,抽了些时间,写了段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.

搜索更多相关主题的帖子: 开源 自动 下载 中国 论坛 
2007-10-22 13:55
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
收藏
得分:0 

如果要扩展为多线,indy也提供了
fIdHttp.Request.ContentRangeStart
fIdHttp.Request.ContentRangeEnd

ftp可以通过发送命令 rest来实现下载某一指定模块

2007-10-22 13:59
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
收藏
得分:0 
我使用的是d6,使用d7的朋友所自带的indy版本是不一样的的,请参考相关文档
2007-10-22 14:15
缘吇弹
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:地球
等 级:版主
威 望:43
帖 子:3038
专家分:27
注 册:2007-7-2
收藏
得分:0 
我用的是D7.
帮你顶一个!

Repeat  Life=Study;Until (death);
2007-10-22 21:31
chb592657370
Rank: 1
来 自:武汉交通职业学院
等 级:新手上路
帖 子:120
专家分:0
注 册:2006-12-9
收藏
得分:0 
我D6和D7一起用的,我初学Delphi,好多地方不是很熟悉,特别是多线程。好东西,学习了,非常感谢。

既然剑不如人,就要剑法胜于人!
2008-05-19 13:51
paome
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2008-6-13
收藏
得分:0 
好多西,谢谢分享
2008-06-13 23:54
快速回复:[开源][原创]关于自动更新的下载部分
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024155 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved