線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4367
推到 Plurk!
推到 Facebook!

如何知道TIdFtp 已經全部下載完畢

答題得分者是:P.D.
xnium
一般會員


發表:27
回覆:26
積分:10
註冊:2007-09-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-06-23 18:55:28 IP:58.210.xxx.xxx 訂閱
請教下各位先進:用Indy的TIdFtp,做的客戶端,如何才能知道我的下載任務已經全部完成了呢?
我是想做个自动更新程序,先检查是否有新的版本,有的话,就从ftp站点上下载,下载完毕新版本资料后,调用主程序。

------
对岸的菜鸟,但是很喜欢用delphi!
編輯記錄
xnium 重新編輯於 2009-06-24 00:05:45, 註解 無‧
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-06-24 22:35:54 IP:61.67.xxx.xxx 未訂閱
這是一支完整的FTP下載程式, 我不提供原始碼, 僅提供程式碼給你參考, IDFTP 該有的EVENT 都有範例寫法
我不知道你用的INDY是幾版的, 我的是 DELPHI5 INDY6, 或許高版本會有不同的寫法

[code delphi]
unit P_DownLoad;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Delay, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdFTP,
ComCtrls, StdCtrls, ini, cl_crypt32, FileCtrl;

type
TForm_DownLoad = class(TForm)
Label1: TLabel;
StatusBar1: TStatusBar;
TreeView1: TTreeView;
IdFTP1: TIdFTP;
ProgressBar1: TProgressBar;
Delay1: TDelay;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure IdFTP1Connected(Sender: TObject);
procedure IdFTP1Disconnected(Sender: TObject);
procedure IdFTP1Status(axSender: TObject; const axStatus: TIdStatus;
const asStatusText: String);
procedure IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
procedure IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
procedure IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
private
{ Private declarations }
AbortTransfer: Boolean;
TransferrignData: Boolean;
BytesToTransfer: LongWord;
STime: TDateTime;
procedure DownLoad;
procedure StartRun(Sender: TObject; var Done: Boolean);
public
{ Public declarations }
end;

var
Form_DownLoad: TForm_DownLoad;

implementation
uses U_VarDef, D_DownLoad;
{$R *.DFM}
var
AverageSpeed: Double = 0;

procedure TForm_DownLoad.StartRun(Sender: TObject; var Done: boolean);
var xhandle: longInt;
begin
xhandle:= FindWindow('TForm_DownLoad', nil);
if xhandle=0 then exit;
Application.ProcessMessages;
Application.OnIdle:= nil;
Done:= True;

Form_DownLoad.Caption:= U_VarDef.CompanyName ' 線上更新系統';
Form_DownLoad.Visible:= True;

// 執行下載
DownLoad;
Application.Terminate;
end;

procedure TForm_DownLoad.DownLoad;
var logfile, getfile, dfile, dname: string;
updfile: string;
readed:string;
F3:TextFile;
F1len, F2len, F3len: integer;
F1date, F2date: String;
f3date: TDateTime;
fHandle: integer;
FileRec:TSearchrec;
RootNode: TTreeNode;
i,j: integer;
mIP: string;
d1, d2, d3, d4: string;
updefile: string;
ufile: TStringList;
begin
// 檢查收銀版本是否有更新, 如果有則下載
mIP:= cl_decrypt(trim(readINI('FTP','FTPIP')));
if mIP='' then mIP:= trim(readINI('HOST','DATAIP'));
Label1.Caption:= '正在檢查是否有新版本...';
Label1.Update;
IdFTP1.Host:= mIP;
IdFTP1.Port:= StrtoIntDef(cl_decrypt(trim(readINI('FTP','PORT'))),21);
IdFTP1.User:= cl_decrypt(trim(readINI('FTP','USERNAME')));
IdFTP1.Password:= cl_decrypt(trim(readINI('FTP','PASSWORD')));
try
IdFTP1.Connect;
if IdFTP1.Connected=False then exit;
except
exit;
end;
TreeView1.Items.Clear;
try
// 下載版本資料供檢查是否有新版要下載
IdFTP1.TransferType:= ftBinary;
logfile:= U_VarDef.AppPath 'TEMP\UPDATE.POS';
if FileExists(logfile) then DeleteFile(logfile);
BytesToTransfer:= IdFTP1.Size('UPDATE.POS');
IdFTP1.Get('UPDATE.POS', logfile, True);
Assignfile(F3,logfile);
reset(F3);
repeat
// 取得更新檔檔名(第一列)
readln(F3,readed);
dname:= trim(AnsiUppercase(readed));
if (dname<>'#') and (not Eof(F3)) then begin
Label1.Caption:= '正在檢查' readed '檔是否有新版本...';
Label1.Update;
// 取得更新的位置路徑(第二列)
readln(F3,readed);
readed:= trim(ansiuppercase(readed));
if readed<>'' then dfile:= U_VarDef.AppPath readed '\' dname
else dfile:= U_VarDef.AppPath dname;
// 取得主機檔案日期, 時間(第三列)
readln(F3,readed);
readed:= trim(ansiuppercase(readed));
F2date:= readed;
// 取得主機檔案大小(第四列)
readln(F3,readed);
readed:= trim(ansiuppercase(readed));
F2len:= StrtoIntDef(readed,0);
// 取得本機檔案大小
FindFirst(dfile,faAnyfile,FileRec);
if FileExists(dfile) then begin
F1date:= DateTimetoStr(FileDatetoDateTime(FileRec.Time));
F1len:= FileRec.Size;
end
else begin
F1date:= F2date;
F1len:= F2len;
end;
// 如果(檔案大小不一且本機的檔案日期時間等於主機)
// 或本機的檔案日期時間比主機早(不含當天)
// 或檔案不存在
if ((F1len <> F2len) and (F1date <= F2date)) or
(F1date < F2date) or
(not FileExists(dfile)) then
begin
getfile:= ExtractFileName(dfile);
RootNode:= TreeView1.Items.Add(nil,getfile);
TreeView1.Items.AddChild(RootNode,InttoStr(F2len));
TreeView1.Items.AddChild(RootNode,F2date);
TreeView1.Items.AddChild(RootNode,dfile);
TreeView1.FullExpand;
end;
end;
until (readed='#') or (Eof(F3));
CloseFile(F3);

// 開始更新
TreeView1.TopItem;
if TreeView1.Items.Count>0 then begin
j:= TreeView1.Items.Count div 4;
for i:= 0 to j-1 do begin
RootNode:= TreeView1.Items[i (i*3)];
d1:= trim(RootNode.Item[0].Text); // bytes
d2:= trim(RootNode.Item[1].Text); // file date
d3:= trim(RootNode.Item[2].Text); // file path
getfile:= ExtractFileName(d3);
dfile:= d3;
F2len:= StrtoIntDef(d1,-1);
updfile:= U_VarDef.AppPath 'UPDATE\' getfile;
Label1.Caption:= '正在下載' getfile '檔的新版本...';
Label1.Update;
// 取得主機端檔案大小
BytesToTransfer:= IdFTP1.Size(getfile);
// 下載到暫存區
IdFTP1.Get(getfile, updfile, True);
// 取得本機檔案大小
FindFirst(dfile,faAnyfile,FileRec);
try
d4:= DateTimetoStr(FileDatetoDateTime(FileRec.Time));
except
d4:= '';
end;

// 未避免下載一半失敗也會造成更新, 要比對下載回來的檔案
// 與主機取得的檔案大小是否一致(F2len)
FindFirst(updfile,faAnyfile,FileRec);
if FileExists(updfile) then F3len:= FileRec.Size
else F3len:= 0;
if F2len=F3len then begin
// 如果是 serial.db, pinsu.db 及 main exe 由於程式被開啟無法更新
// 所以要先置入 update 目錄, 再由 extdown 來執行更新
// 轉入update 目錄, 產生 serial.upd檔案, 內記錄
// 更新路徑, 更新檔案
if (getfile='SERIAL.DB') or (getfile='PINSU.DB') or
(getfile='OTHERSYS.DB') or (getfile='LOGON.GDB') or
(getfile='MENU.GDB') or (getfile='MENU.DB') or
(getfile='AUTHOR.DB') or (getfile='DATA.INI') or
(getfile='DOWNLOAD.DLL') or (getfile='USER.DB') or
(getfile=D_DownLoad.mainexe) then
begin
updefile:= U_VarDef.AppPath 'UPDATE\'
ChangeFileExt(getfile,'.upd');
uFile:= TStringList.Create;
uFile.Add(dfile);
uFile.Add(d2);
uFile.Add(d1);
uFile.Add('#');
uFile.SaveToFile(updefile);
uFile.Free;
end
else begin
F3date:= StrtoDateTime(d2);
copyFile(pChar(updfile),pChar(dfile),False);
// 改變檔案日期為下載的檔案日期
fHandle:= FileOpen(dfile, fmOpenWrite);
FileSetDate(fHandle, DateTimeToFileDate(F3date));
FileClose(fHandle);
DeleteFile(updfile);
end;
end;
end;
logfile:= U_VarDef.AppPath 'Download.log';
TreeView1.TopItem;
TreeView1.SaveToFile(logfile);
Label1.Caption:= '更新完畢';
Label1.Update;
end
else begin
Label1.Caption:= '目前的版本己是最新的';
Label1.Update;
sleep(2000);
end;
except
on E:Exception do begin
StatusBar1.Panels[0].Text:= '檔案下載失敗' E.message;
end;
end;
IdFTP1.Disconnect;
end;

procedure TForm_DownLoad.FormCreate(Sender: TObject);
var mdir: string;
begin
// 設定系統格式, iniFile Define in SYS_UT
inipath:= U_VarDef.miniFile;
U_VarDef.AppPath := trim(readINI('DATA','APPLICATION'));
U_VarDef.DllUt := trim(readINI('DATA','DLLUT'));
U_VarDef.DllPath := trim(readINI('DATA','DLLPATH'));
U_VarDef.ndisk := trim(readINI('DATA','NDISK'));
U_VarDef.unc := trim(readINI('DATA','UNC'));
U_VarDef.CompanyName:= trim(readINI('SYSVALUE','TITLE'));

try
mdir:= U_VarDef.AppPath 'UPDATE';
if not DirectoryExists(mdir) then CreateDir(mdir);
except
end;

// 設定日期格式
LongTimeFormat:= 'HH:mm:ss';
ShortDateFormat:='yyyy/MM/dd';
DateSeparator:='/';

Application.OnIdle:= StartRun;
end;

procedure TForm_DownLoad.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:= caFree;
Form_DownLoad:= nil;
end;

procedure TForm_DownLoad.IdFTP1Connected(Sender: TObject);
begin
StatusBar1.Panels[0].Text:= '已連線';
StatusBar1.Update;
end;

procedure TForm_DownLoad.IdFTP1Disconnected(Sender: TObject);
begin
StatusBar1.Panels[0].Text:= '離線...';
StatusBar1.Update;
end;

procedure TForm_DownLoad.IdFTP1Status(axSender: TObject; const axStatus: TIdStatus;
const asStatusText: String);
begin
StatusBar1.Panels[0].Text:= asStatusText;
StatusBar1.Update;
end;

procedure TForm_DownLoad.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
Var S: String;
TotalTime: TDateTime;
H, M, Sec, MS: Word;
DLTime: Double;
begin
TotalTime:= Now - STime;
DecodeTime(TotalTime, H, M, Sec, MS);
Sec:= Sec M * 60 H * 3600;
DLTime:= Sec MS / 1000;
if DLTime > 0 then AverageSpeed:= (AWorkCount / 1024) / DLTime;

S:= FormatFloat('0.00 KB/s', AverageSpeed);
case AWorkMode of
wmRead: StatusBar1.Panels[0].Text := '下載速度 ' S;
wmWrite: StatusBar1.Panels[0].Text:= '上傳速度 ' S;
end;
StatusBar1.Update;

if AbortTransfer then IdFTP1.Abort;
ProgressBar1.Position:= AWorkCount;
ProgressBar1.Update;
AbortTransfer:= False;
Application.ProcessMessages;
end;

procedure TForm_DownLoad.IdFTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCountMax: Integer);
begin
TransferrignData:= True;
AbortTransfer:= False;
STime:= Now;
if AWorkCountMax > 0 then ProgressBar1.Max:= AWorkCountMax
else ProgressBar1.Max:= BytesToTransfer;
AverageSpeed:= 0;
end;

procedure TForm_DownLoad.IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
StatusBar1.Panels[0].Text := '傳送完成';
StatusBar1.Update;
BytesToTransfer:= 0;
TransferrignData:= False;
ProgressBar1.Position:= 0;
AverageSpeed:= 0;
end;

end.
[/code]
xnium
一般會員


發表:27
回覆:26
積分:10
註冊:2007-09-05

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-06-24 23:36:45 IP:117.80.xxx.xxx 訂閱
多谢版主大人的帮助,小弟受益非浅!
接受答案了
------
对岸的菜鸟,但是很喜欢用delphi!
系統時間:2024-04-20 13:36:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!