日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

delphi中利用Indy的TIdFtp控件实现FTP协议

發(fā)布時(shí)間:2023/12/4 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 delphi中利用Indy的TIdFtp控件实现FTP协议 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

delphi中利用Indy的TIdFtp控件實(shí)現(xiàn)FTP協(xié)議版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。現(xiàn)在很多應(yīng)用都需要上傳與下載大型文件,通過HTTP方式上傳大文件有一定的局限性。幸好FTP作為一個(gè)非常老而且非常成熟的協(xié)議可以高效穩(wěn)定地完 成大文件的上傳下載,并且可以完美地實(shí)現(xiàn)續(xù)傳。就拿我寫的電影服務(wù)器管理端程序來說,各種方案比較后,發(fā)現(xiàn)使用FTP可以完美地實(shí)現(xiàn)要求。但是要通過 WinSocket庫實(shí)現(xiàn)FTP比較麻煩,幸好有Indy--一個(gè)包裝了大多數(shù)網(wǎng)絡(luò)協(xié)議的組件包。通過Indy,程序設(shè)計(jì)人員可以通過阻塞方式進(jìn)行編程,可以拋開蹩腳的Winsocket異步模式,采用與Unix系統(tǒng)上等同的阻塞編程模式進(jìn)行。這樣,程序員就可以很好的處理程序的運(yùn)行流程。下面,我們進(jìn)入到Indy的TIdFtp世界。1.控件的說明使用Indy 9中的TIdFtp控件可以實(shí)現(xiàn)通過FTP方式進(jìn)行文件的上傳與下載。2.控件的具體使用(1)控件屬性設(shè)置默 認(rèn)屬性即可,與服務(wù)器連接直接相關(guān)的屬性如主機(jī)名與用戶等在建立連接時(shí)進(jìn)行設(shè)定。需要設(shè)定的是RecvBufferSize和 SendBufferSize兩屬性的值。另外需要根據(jù)要傳輸?shù)奈募愋椭付═ransferType屬性,而其他屬性按默認(rèn)值設(shè)定即可。RecvBufferSize說明(默認(rèn)值為8192字節(jié)):該屬性為整型變量,用于指定連接所用的接受緩沖區(qū)大小。SendBufferSize 說明(默認(rèn)值為32768字節(jié)):該屬性也為整型變量,用于指定連接所用的發(fā)送緩沖區(qū)的最大值。該屬性在WriteStream方法中時(shí),可用于 TStream指定要發(fā)送內(nèi)容的塊數(shù)。如果要發(fā)送的內(nèi)容大于本屬性值,則發(fā)送內(nèi)容被分為多個(gè)塊發(fā)送。TransferType說明(默認(rèn) 值為ftBinary):該屬性為TIdFTPTransferType型變量。用于指定傳輸內(nèi)容是二進(jìn)制文件(ftBinary )還是ASCII文件(ftASCII)。應(yīng)用程序需要使用二進(jìn)制方式傳輸可執(zhí)行文件、壓縮文件和多媒體文件等;而使用ASCII方式傳輸文本或超文本等 文本型數(shù)據(jù)。(2)控件的事件響應(yīng)OnDisconnected響應(yīng):TNotifyEvent類,用于響應(yīng)斷開(disconnect)事件。當(dāng)Disconnect方法被調(diào)用用來關(guān)閉Socket的時(shí)候,觸發(fā)該響應(yīng)。應(yīng)用程序必須指定該事件響應(yīng)的過程,以便對(duì)該斷開事件進(jìn)行相應(yīng)。OnStatus 響應(yīng):TIdStatusEvent類。該響應(yīng)在當(dāng)前連接的狀態(tài)變化時(shí)被觸發(fā)。該事件可由DoStatus方法觸發(fā)并提供給事件控制器屬性。 axStatus是當(dāng)前連接的TIdStatus值;aaArgs是一個(gè)可選的參數(shù)用于格式化函數(shù),它將用于構(gòu)造表現(xiàn)當(dāng)前連接狀態(tài)的文本消息。OnWork 響應(yīng):OnWord是TWorkEvent類事件的響應(yīng)控制器。OnWork用于關(guān)聯(lián)DoWork方法當(dāng)緩沖區(qū)讀寫操作被調(diào)用時(shí)通知Indy組件和類。它 一般被用于控制進(jìn)度條和視窗元素的更新。AWorkMode表示當(dāng)前操作的模式,其中:wmRead-組件正在讀取數(shù)據(jù);wmWrite-組件正在發(fā)送數(shù) 據(jù)。AWorkCount指示當(dāng)前操作的字節(jié)計(jì)數(shù)。OnWorkBegin響應(yīng):TWorkBeginEvent類。當(dāng)緩沖區(qū)讀 寫操作初始化時(shí),該事件關(guān)聯(lián)BeginWork方法用于通知Indy組件和類。它一般被用于控制進(jìn)度條和視窗元素的更新。AWorkMode表示當(dāng)前操作 的模式,其中:wmRead-組件正在讀取數(shù)據(jù);wmWrite-組件正在發(fā)送數(shù)據(jù)。AWorkCountMax用于指示發(fā)送到OnWorkBegin事 件的操作的最大字節(jié)數(shù),0值代表未知。OnWorkEnd響應(yīng):TWorkEndEvent類。當(dāng)緩沖區(qū)讀寫操作終止時(shí),該事件 關(guān)聯(lián)EndWork方法用于通知Indy組件和類。AWorkMode表示當(dāng)前操作的模式,其中:wmRead-組件正在讀取數(shù)據(jù);wmWrite-組件 正在發(fā)送數(shù)據(jù)。AWorkCount表示操作的字節(jié)數(shù)。在事件響應(yīng)中,主要通過上述五種事件響應(yīng)來控制程序。在一般情況下,在 OnDisconnected中設(shè)定連接斷開的界面通知;在OnStatus中設(shè)定當(dāng)前操作的狀態(tài);在OnWork中實(shí)現(xiàn)傳輸中狀態(tài)條和其他參數(shù)的顯示; 而在OnWorkBegin和OnWorkEnd中分別設(shè)定開始傳輸和傳輸結(jié)束時(shí)的界面。(3)連接遠(yuǎn)程服務(wù)器完 成了設(shè)定控件屬性和實(shí)現(xiàn)了控件的事件響應(yīng)后,就可以與服務(wù)器進(jìn)行交互和傳輸了。在連接之前,應(yīng)首先判斷IdFtp是否處于連接狀態(tài),如果 Connected為False,則通過界面控件或其他方式指定與服務(wù)器連接相關(guān)的一些TCP類屬性的設(shè)置,分別是:Host(主機(jī)名):String、 Username(用戶名):String、Password(密碼):String,也可以指定Port(端口)。之后調(diào)用Connect方法連接遠(yuǎn)程 服務(wù)器,如果無異常出現(xiàn)則連接成功建立。過程說明:procedure Connect(AAutoLogin: boolean; const ATimeout: Integer);該過程連接遠(yuǎn)程FTP服務(wù)器屬性:AAutoLogin: boolean = True連接后自動(dòng)登錄,該參數(shù)默認(rèn)為True。const ATimeout: Integer = IdTimeoutDefault超時(shí)時(shí)間,單位:秒。示例代碼:if IdFTP1.Connected then tryif TransferrignData then IdFTP1.Abort;IdFTP1.Quit;finallyendelse with IdFTP1 do tryUsername := UserIDEdit.Text;Password := PasswordEdit.Text;Host := FtpServerEdit.Text;Connect;ChangeDir(CurrentDirEdit.Text);finallyend;(4)改變目錄連 接建立后,可以改變當(dāng)前FTP會(huì)話所在的目錄。對(duì)于已知絕對(duì)路徑的情況下,可以直接調(diào)用ChangeDir(const ADirName: string)方法來轉(zhuǎn)換目錄,ADirName表示服務(wù)器上的文件系統(tǒng)目錄,另外還可以調(diào)用ChangeDirUp回到上級(jí)目錄。如 果未知路徑,則可以通過List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean)過程獲取遠(yuǎn)程服務(wù)器的當(dāng)前目錄結(jié)構(gòu),此時(shí)必須設(shè)定TransferType為ftASCII(ASCII模式),其中:ADest保存當(dāng) 前目錄結(jié)構(gòu),可以在后續(xù)程序中調(diào)用該列表。另外可以通過RetrieveCurrentDir方法獲取當(dāng)前目錄名。過程說明:procedure ChangeDir(const ADirName: string);改變工作目錄屬性const ADirName: string遠(yuǎn)程服務(wù)器的目錄描述說明:該過程實(shí)際上是實(shí)現(xiàn)了FTP CWD命令。procedure ChangeDirUp;到上一級(jí)目錄function RetrieveCurrentDir: string;該函數(shù)返回當(dāng)前目錄名procedure List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean);列出當(dāng)前目錄所有文件和子目錄及其屬性參數(shù):ADest: TStrings保存文件及子目錄的返回結(jié)果const ASpecifier: string = ''文件掩碼,用于列出符合條件的文件const ADetails: boolean = true包含文件和子目錄屬性property DirectoryListing: TIdFTPListItems;返回文件及目錄結(jié)構(gòu)的列表示例代碼:LS := TStringList.Create;tryIdFTP1.ChangeDir(DirName);IdFTP1.TransferType := ftASCII;CurrentDirEdit.Text := IdFTP1.RetrieveCurrentDir;DirectoryListBox.Items.Clear;IdFTP1.List(LS);DirectoryListBox.Items.Assign(LS);if DirectoryListBox.Items.Count > 0 thenif AnsiPos('total', DirectoryListBox.Items[0]) > 0 then DirectoryListBox.Items.Delete(0);finallyLS.Free;end;(5)下載的實(shí)現(xiàn)在 下載之前,必須查看DirectoryListing.Items[sCurrFile].ItemType是否為文件,如返回為 ditDirectory則代表當(dāng)前文件名為目錄,不能下載,必須導(dǎo)向到文件才可。如為文件,則可以進(jìn)行下載。在下載前,設(shè)定傳輸?shù)念愋蜑槎M(jìn)制文件,并 且指定本地要保存的路徑。通過調(diào)用Get方法,實(shí)現(xiàn)文件的下載。下載過程較慢,可以考慮將其放到線程中實(shí)現(xiàn)。過程說明:procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean); overload;procedure Get(const ASourceFile: string; const ADestFile: string; const ACanOverwrite: boolean; AResume: Boolean); overload;從遠(yuǎn)程服務(wù)器上獲取文件。屬性說明:const ASourceFile: string遠(yuǎn)程服務(wù)器上的源文件名const ADestFile: string保存到客戶機(jī)上的文件名const ACanOverwrite: boolean = false重寫同名文件AResume: Boolean = false是否進(jìn)行斷點(diǎn)續(xù)傳示例代碼:SaveDialog1.FileName := Name;if SaveDialog1.Execute then beginSetFunctionButtons(false);IdFTP1.TransferType := ftBinary;BytesToTransfer := IdFTP1.Size(Name);if FileExists(Name) then begincase MessageDlg('File aready exists. Do you want to resume the download operation?',mtConfirmation, mbYesNoCancel, 0) ofmrYes: beginBytesToTransfer := BytesToTransfer - FileSizeByName(Name);IdFTP1.Get(Name, SaveDialog1.FileName, false, true);end;mrNo: beginIdFTP1.Get(Name, SaveDialog1.FileName, true);end;mrCancel: beginexit;end;end;endelse beginIdFTP1.Get(Name, SaveDialog1.FileName, false);end;(6)上傳的實(shí)現(xiàn)上傳的實(shí)現(xiàn)與下載類似,通過put方法即可。過程說明:procedure Put(const ASource: TStream; const ADestFile: string; const AAppend: boolean); overload;procedure Put(const ASourceFile: string; const ADestFile: string; const AAppend: boolean); overload;上傳文件至服務(wù)器屬性說明:const ASourceFile: string將要被上傳的文件const ADestFile: string = ''服務(wù)器上的目標(biāo)文件名const AAppend: boolean = false是否繼續(xù)上傳代碼示例:if IdFTP1.Connected then beginif UploadOpenDialog1.Execute then tryIdFTP1.TransferType := ftBinary;IdFTP1.Put(UploadOpenDialog1.FileName, ExtractFileName(UploadOpenDialog1.FileName));//可以在此添加改變目錄的代碼;finally//完成清除工作end;end;(7)刪除的實(shí)現(xiàn)刪除文件使用Delete方法,該方法刪除指定的文件,刪除對(duì)象必須為文件。如果要?jiǎng)h除目錄則使用RemoveDir方法。過程說明:procedure Delete(const AFilename: string);刪除文件procedure RemoveDir(const ADirName: string);刪除文件夾,根據(jù)不同的服務(wù)器刪除文件夾有不同的要求。有些服務(wù)器不允許刪除非空文件夾,程序員需要添加清空目錄的代碼。上述兩個(gè)過程的參數(shù)均為目標(biāo)名稱代碼示例:if not IdFTP1.Connected then exit;Name := IdFTP1.DirectoryListing.Items[iCurrSelect].FileName;if IdFTP1.DirectoryListing.Items[iCurrSelect].ItemType = ditDirectory then tryidftp1.RemoveDir(Name);finallyendelsetryidftp1.Delete(Name);finallyend;(8)后退的實(shí)現(xiàn)后退在實(shí)際上是目錄操作的一種,可以簡單的改變當(dāng)前目錄為..來實(shí)現(xiàn),也可以通過回到上級(jí)目錄來實(shí)現(xiàn)。(9)取消的實(shí)現(xiàn)在IdFtp的傳輸過程中,可以隨時(shí)使用abort方法取消當(dāng)前操作。可以的OnWork事件的實(shí)現(xiàn)中來確定何時(shí)取消操作。代碼示例://取消按鈕的OnClick響應(yīng)procedure TMainForm.AbortButtonClick(Sender: TObject);beginAbortTransfer := true;end;//IdFTP的OnWork事件響應(yīng)procedure TMainForm.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;const AWorkCount: Integer);begin... if AbortTransfer then IdFTP1.Abort;AbortTransfer := false;end;(10)斷點(diǎn)續(xù)傳的實(shí)現(xiàn)斷點(diǎn)續(xù)傳就是在上傳或下載過程開始時(shí),判斷已經(jīng)傳輸過的文件是否上傳輸完畢,如果傳輸沒有成功完成,則在上次中斷處繼續(xù)進(jìn)行傳輸工作。實(shí)現(xiàn)該功能需要兩個(gè)重要的操作,首先是判斷文件的大小信息,其次是在傳輸過程Get和Put中指定上傳的行為。判斷服務(wù)器上文件的大小使用函數(shù)Size(FileName)。在下載過程中,比較本地文件和遠(yuǎn)程文件的信息,然后在Get中指定AResume := True即可。而上傳也一樣,指定Put的AAppend := True就可以了。 在 前面我們講過,Indy的網(wǎng)絡(luò)操作大部分是阻塞模式的,TIdFtp也不例外。這樣在上述各個(gè)操作運(yùn)行過程的時(shí)候用戶界面被暫時(shí)凍結(jié),必須要等待調(diào)用返回 才能繼續(xù)用戶操作界面響應(yīng)。所以在實(shí)際編程中,需要使用多線程的方式來保證戶界面的響應(yīng)。Windows系統(tǒng)可以使用CreateThread系統(tǒng)調(diào)用來 創(chuàng)建線程,但是在使用的時(shí)候需要開發(fā)人員做很多額外的工作來保證線程的同步等問題。而Indy中也包含了實(shí)現(xiàn)多線程的控件 TIdThreadComponent,相對(duì)比之下該控件實(shí)現(xiàn)多線程時(shí)更加方便,也更容易控制。我將在后續(xù)的文章里為大家介紹 TIdThreadCOmponent的使用方法。下載的一些代碼接下來我們來寫最主要的代碼,也就是下載部分了,首先來看HTTP協(xié)議的: procedure TForm1.HttpDownLoad(aURL, aFile: string; bResume: Boolean); vartStream: TFileStream; begin //Http方式下載if FileExists(aFile) then //如果文件已經(jīng)存在tStream := TFileStream.Create(aFile, fmOpenWrite) elsetStream := TFileStream.Create(aFile, fmCreate);if bResume then //續(xù)傳方式beginIdHTTP1.Request.ContentRangeStart := tStream.Size - 1;tStream.Position := tStream.Size - 1; //移動(dòng)到最后繼續(xù)下載IdHTTP1.Head(aURL);IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength;end else //覆蓋或新建方式beginIdHTTP1.Request.ContentRangeStart := 0;end;tryIdHTTP1.Get(aURL, tStream); //開始下載finallytStream.Free;end; end; 這里我們同樣使用IdHTTP的Get過程,函數(shù)的aURL是網(wǎng)址,aFile是保存的文件名,bResume確定是否續(xù)傳,需要注意的就是續(xù)傳方式時(shí)的代碼:IdHTTP1.Request.ContentRangeStart := tStream.Size - 1;tStream.Position := tStream.Size - 1; //移動(dòng)到最后繼續(xù)下載IdHTTP1.Head(aURL);IdHTTP1.Request.ContentRangeEnd := IdHTTP1.Response.ContentLength; 第 一行我們將下載開始位置設(shè)置為讀入文件流的末尾,也就是設(shè)置為已經(jīng)下載了的那部分文件的大小,第二行我們將文件流本身也指向自己的末尾,第三行我們通過 Head過程得到網(wǎng)址頭信息,在第四行將頭信息的文件總大小賦值給下載的結(jié)束的位置,至于這里為什么第一行和第二行代碼最后都要-1,我當(dāng)時(shí)沒有加-1的 時(shí)候在續(xù)下載一個(gè)完整的已經(jīng)下載的文件的時(shí)候總是提示錯(cuò)誤,最后跟蹤IdHTTP的代碼發(fā)現(xiàn)他在處理下載范圍的時(shí)候如果開始的位置和結(jié)束位置一樣時(shí)會(huì)引發(fā) 將浮點(diǎn)數(shù)轉(zhuǎn)為整數(shù)的錯(cuò)誤,因而這里加上-1防止這種錯(cuò)誤發(fā)生,另外一種處理方法就是比較如果開始位置等于結(jié)束位置就退出也是可以的。 再來看FTP協(xié)議的下載過程: procedure TForm1.FtpDownLoad(aURL, aFile: string; bResume: Boolean); vartStream: TFileStream;sName, sPass, sHost, sPort, sDir: string; begin //ftp方式下載if FileExists(aFile) then //建立文件流tStream := TFileStream.Create(aFile, fmOpenWrite) elsetStream := TFileStream.Create(aFile, fmCreate);GetFTPParams(aURL, sName, sPass, sHost, sPort, sDir);with IdFTP1 dotryif Connected then Disconnect; //重新連接Username := sName;Password := sPass;Host := sHost;Port := StrToInt(sPort);Connect;exceptexit;end;IdFTP1.ChangeDir(sDir); //改變目錄BytesToTransfer := IdFTP1.Size(aFile);tryif bResume then //續(xù)傳begintStream.Position := tStream.Size;IdFTP1.Get(aFile, tStream, True);end elsebeginIdFTP1.Get(aFile, tStream, False);end;finallytStream.Free;end; end; 這 個(gè)過程中我們就用到了GetFTPParams()函數(shù)將網(wǎng)址的用戶名、密碼、主機(jī)地址、端口、路徑等信息分離出來,IdFTP利用這些信息登陸服務(wù)器并 到相應(yīng)目錄,最后利用Get()過程就很容易實(shí)現(xiàn)下載了,它的續(xù)傳就比HTTP協(xié)議要簡單很多,因?yàn)镮dFTP的Get()本身就支持續(xù)傳。 這里我簡單穿插一點(diǎn)的內(nèi)容,一個(gè)服務(wù)器是否支持?jǐn)帱c(diǎn)續(xù)傳,我們可以通過發(fā)送"REST 1"FTP指令來檢測(cè),如果返回350則表示支持。 最后我們根據(jù)網(wǎng)址來確定使用什么協(xié)議來下載: function TForm1.GetProt(aURL: string): Byte; begin //檢測(cè)下載的地址是http還是ftpResult := 0;if Pos('http', LowerCase(aURL)) = 1 thenResult := 1; //http協(xié)議if Pos('ftp', LowerCase(aURL)) = 1 thenResult := 2; //ftp協(xié)議 end; 這個(gè)函數(shù)根據(jù)網(wǎng)址返回整數(shù)供我們使用。 procedure TForm1.MyDownLoad(aURL, aFile: string; bResume: Boolean); begincase GetProt(aURL) of0: ShowMessage('不可識(shí)別的地址!');1: HttpDownLoad(aURL, aFile, bResume);2: FtpDownLoad(aURL, aFile, bResume);end; end; 這個(gè)過程就利用GetProt()函數(shù)返回的整數(shù)執(zhí)行相應(yīng)的協(xié)議下載過程。 (2) 接下來看看每個(gè)按鈕的代碼,有了上面的函數(shù),按鈕的代碼就簡單多了: 下載按鈕: procedure TForm1.Button1Click(Sender: TObject); varaURL, aFile: string; beginaURL := ComboBox1.Text; //下載地址,例如"http://www.2ccc.com/update/demo.exe";aFile := GetURLFileName(aURL); //得到文件名,例如"demo.exe"if FileExists(aFile) thenbegincase MessageDlg('文件已經(jīng)存在,是否續(xù)傳?', mtConfirmation, mbYesNoCancel, 0) ofmrYes: MyDownLoad(aURL, aFile, True); //續(xù)傳mrNo: MyDownLoad(aURL, aFile, False); //覆蓋mrCancel: Exit; //取消end;end else MyDownLoad(aURL, aFile, False); //建立新文件下載 end; MessageDlg()函數(shù)彈出一個(gè)對(duì)話框讓用戶選擇續(xù)傳、覆蓋還是取消下載。 中斷按鈕: procedure TForm1.Button2Click(Sender: TObject); beginAbortTransfer := True; end; 前 面忘了介紹,所以這里大家看不明白,AbortTransfer是我們定義的一個(gè)私有變量,在開始下載的時(shí)候?qū)⑺O(shè)為False,下載的過程中隨時(shí)監(jiān)測(cè)這 個(gè)變量,一旦變?yōu)門rue就利用IdHTTP的Disconnect和IdFTP1的Abort方法中斷下載,如果沒有下載完就中斷,那程序的目錄中就會(huì) 有一個(gè)下載不完整的程序或者其他東西,下次再下載的時(shí)候我們就可以選擇續(xù)傳來完成剩下的下載過程。 procedure TForm1.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer); beginAbortTransfer := False; …… end; 在IdHTTP1和IdFTP的OnWorkBegin事件我們就將AbortTransfer設(shè)置為False了,在他們的Work事件中,我們檢測(cè)AbortTransfer變量來完成是否中斷的操作。 procedure TForm1.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;const AWorkCount: Integer); beginif AbortTransfer thenbegin //中斷下載IdHTTP1.Disconnect;IdFTP1.Abort;end;ProgressBar1.Position := AWorkCount;Application.ProcessMessages; end; (3) 最后是連接狀態(tài)等信息的代碼: 在IdHTTP和IdFTP的OnStatus事件寫入: procedure TForm1.IdHTTP1Status(ASender: TObject; const AStatus: TIdStatus;const AStatusText: string); beginListBox1.ItemIndex := ListBox1.Items.Add(AStatusText); end; 因?yàn)镮dHTTP和IdFTP在OnWork、OnStatus等事件上執(zhí)行的代碼都是一樣的,所以我們只用寫其中一個(gè)的代碼,然后另外一個(gè)選擇相同的事件就OK了。圖8.3.4 3.全部代碼寫完收工,F9運(yùn)行一下看看效果,是不是能斷點(diǎn)續(xù)傳。 【程序小結(jié)】 本程序主要的功能由IdHTTP和IdFTP組件完成,主要掌握他們的Get過程實(shí)現(xiàn)斷點(diǎn)續(xù)傳的方法以及字符串的分析分解方法,這里我們同樣使用了流格式,不過這次不是內(nèi)存流而是文件流。通過本例,讀者應(yīng)該初步掌握調(diào)試程序時(shí)斷點(diǎn)的使用,事件代碼的共用等。 【作者后話】 在寫完這篇文章不久,作者偶然間察看了Indy系列組件的幫助,發(fā)現(xiàn)一個(gè)封裝了分析URL結(jié)構(gòu)的類TIdURI,在IdURI單元,這個(gè)類可以很輕松的將我們上面的GetFTPParams()函數(shù)的功能實(shí)現(xiàn),例如: varURI: TIdURI; beginURI := TIdURI.Create(aURL); //建立trysProtocol := URI.Protocol; //協(xié)議sHost := URI.Host; //主機(jī)//……等等都可以通過URI的屬性得到finallyURI.Free;end; end; 使用此類我們的程序可以變得更簡單,如何修改就留給讀者自己去完善吧。

轉(zhuǎn)載于:https://my.oschina.net/u/582827/blog/872827

總結(jié)

以上是生活随笔為你收集整理的delphi中利用Indy的TIdFtp控件实现FTP协议的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。