如何知道TIdFtp 已經全部下載完畢 |
答題得分者是:P.D.
|
xnium
一般會員 發表:27 回覆:26 積分:10 註冊:2007-09-05 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
這是一支完整的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 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |