六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

使用Indy的TIdFtp控件完成FTP協議

[摘要]現在很多應用都需要上傳與下載大型文件,通過HTTP方式上傳大文件有一定的局限性。幸好FTP作為一個非常老而且非常成熟的協議可以高效穩定地完成大文件的上傳下載,并且可以完美地實現續傳。就拿我寫的電影服務器管理端程序來說,各種方案比較后,發現使用FTP可以完美地實現要求。但是要通過WinSocket庫...
現在很多應用都需要上傳與下載大型文件,通過HTTP方式上傳大文件有一定的局限性。幸好FTP作為一個非常老而且非常成熟的協議可以高效穩定地完成大文件的上傳下載,并且可以完美地實現續傳。就拿我寫的電影服務器管理端程序來說,各種方案比較后,發現使用FTP可以完美地實現要求。但是要通過WinSocket庫實現FTP比較麻煩,幸好有Indy--一個包裝了大多數網絡協議的組件包。

  通過Indy,程序設計人員可以通過阻塞方式進行編程,可以拋開蹩腳的Winsocket異步模式,采用與Unix系統上等同的阻塞編程模式進行。這樣,程序員就可以很好的處理程序的運行流程。 下面,我們進入到Indy的TIdFtp世界。

  1.控件的說明

  使用Indy 9中的TIdFtp控件可以實現通過FTP方式進行文件的上傳與下載。

  2.控件的具體使用

  (1)控件屬性設置

  默認屬性即可,與服務器連接直接相關的屬性如主機名與用戶等在建立連接時進行設定。需要設定的是RecvBufferSize和SendBufferSize兩屬性的值。另外需要根據要傳輸的文件類型指定TransferType屬性,而其他屬性按默認值設定即可。

  RecvBufferSize說明(默認值為8192字節):該屬性為整型變量,用于指定連接所用的接受緩沖區大小。

  SendBufferSize說明(默認值為32768字節):該屬性也為整型變量,用于指定連接所用的發送緩沖區的最大值。該屬性在WriteStream方法中時,可用于TStream指定要發送內容的塊數。如果要發送的內容大于本屬性值,則發送內容被分為多個塊發送。

  TransferType說明(默認值為ftBinary):該屬性為TIdFTPTransferType型變量。用于指定傳輸內容是二進制文件(ftBinary )還是ASCII文件(ftASCII)。應用程序需要使用二進制方式傳輸可執行文件、壓縮文件和多媒體文件等;而使用ASCII方式傳輸文本或超文本等文本型數據。

  (2)控件的事件響應

  OnDisconnected響應:TNotifyEvent類,用于響應斷開(disconnect)事件。當Disconnect方法被調用用來關閉Socket的時候,觸發該響應。應用程序必須指定該事件響應的過程,以便對該斷開事件進行相應。

  OnStatus響應:TIdStatusEvent類。該響應在當前連接的狀態變化時被觸發。該事件可由DoStatus方法觸發并提供給事件控制器屬性。axStatus是當前連接的TIdStatus值;aaArgs是一個可選的參數用于格式化函數,它將用于構造表現當前連接狀態的文本消息。

  OnWork響應:OnWord是TWorkEvent類事件的響應控制器。OnWork用于關聯DoWork方法當緩沖區讀寫操作被調用時通知Indy組件和類。它一般被用于控制進度條和視窗元素的更新。AWorkMode表示當前操作的模式,其中:wmRead-組件正在讀取數據;wmWrite-組件正在發送數據。AWorkCount指示當前操作的字節計數。

  OnWorkBegin響應:TWorkBeginEvent類。當緩沖區讀寫操作初始化時,該事件關聯BeginWork方法用于通知Indy組件和類。它一般被用于控制進度條和視窗元素的更新。AWorkMode表示當前操作的模式,其中:wmRead-組件正在讀取數據;wmWrite-組件正在發送數據。AWorkCountMax用于指示發送到OnWorkBegin事件的操作的最大字節數,0值代表未知。

  OnWorkEnd響應:TWorkEndEvent類。當緩沖區讀寫操作終止時,該事件關聯EndWork方法用于通知Indy組件和類。AWorkMode表示當前操作的模式,其中:wmRead-組件正在讀取數據;wmWrite-組件正在發送數據。AWorkCount表示操作的字節數。

  在事件響應中,主要通過上述五種事件響應來控制程序。在一般情況下,在OnDisconnected中設定連接斷開的界面通知;在OnStatus中設定當前操作的狀態;在OnWork中實現傳輸中狀態條和其他參數的顯示;而在OnWorkBegin和OnWorkEnd中分別設定開始傳輸和傳輸結束時的界面。

  (3)連接遠程服務器

  完成了設定控件屬性和實現了控件的事件響應后,就可以與服務器進行交互和傳輸了。在連接之前,應首先判斷IdFtp是否處于連接狀態,如果Connected為False,則通過界面控件或其他方式指定與服務器連接相關的一些TCP類屬性的設置,分別是:Host(主機名):String、Username(用戶名):String、Password(密碼):String,也可以指定Port(端口)。之后調用Connect方法連接遠程服務器,如果無異常出現則連接成功建立。

  過程說明:procedure Connect(AAutoLogin: boolean; const ATimeout: Integer);

  該過程連接遠程FTP服務器

  屬性:AAutoLogin: boolean = True

  連接后自動登錄,該參數默認為True。

const ATimeout: Integer = IdTimeoutDefault

  超時時間,單位:秒。

  示例代碼:

if IdFTP1.Connected then
 try
  if TransferrignData then IdFTP1.Abort;
   IdFTP1.Quit;
   finally
   end
  else
   with IdFTP1 do try
    Username := UserIDEdit.Text;
    Password := PasswordEdit.Text;
    Host := FtpServerEdit.Text;
    Connect;
    ChangeDir(CurrentDirEdit.Text);
    finally
   end;

  (4)改變目錄

  連接建立后,可以改變當前FTP會話所在的目錄。對于已知絕對路徑的情況下,可以直接調用ChangeDir(const ADirName: string)方法來轉換目錄,ADirName表示服務器上的文件系統目錄,另外還可以調用ChangeDirUp回到上級目錄。

  如果未知路徑,則可以通過List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean)過程獲取遠程服務器的當前目錄結構,此時必須設定TransferType為ftASCII(ASCII模式),其中:ADest保存當前目錄結構,可以在后續程序中調用該列表。另外可以通過RetrieveCurrentDir方法獲取當前目錄名。

  過程說明:

procedure ChangeDir(const ADirName: string);

  改變工作目錄

  屬性

const ADirName: string

  遠程服務器的目錄描述

  說明:該過程實際上是實現了FTP CWD命令。

procedure ChangeDirUp;

  到上一級目錄

function RetrieveCurrentDir: string;

  該函數返回當前目錄名

procedure List(ADest: TStrings; const ASpecifier: string; const ADetails: boolean);

  列出當前目錄所有文件和子目錄及其屬性

  參數:

ADest: TStrings

  保存文件及子目錄的返回結果

const ASpecifier: string = ''

  文件掩碼,用于列出符合條件的文件

const ADetails: boolean = true

  包含文件和子目錄屬性

property DirectoryListing: TIdFTPListItems;

  返回文件及目錄結構的列表

  示例代碼:

LS := TStringList.Create;

try

IdFTP1.ChangeDir(DirName);

IdFTP1.TransferType := ftASCII;

CurrentDirEdit.Text := IdFTP1.RetrieveCurrentDir;

DirectoryListBox.Items.Clear;

IdFTP1.List(LS);

DirectoryListBox.Items.Assign(LS);

if DirectoryListBox.Items.Count > 0 then

if AnsiPos('total', DirectoryListBox.Items[0]) > 0 then DirectoryListBox.Items.Delete(0);

finally

LS.Free;

end;


  (5)實現下載

  在下載之前,必須查看DirectoryListing.Items[sCurrFile].ItemType是否為文件,如返回為ditDirectory則代表當前文件名為目錄,不能下載,必須導向到文件才可。如為文件,則可以進行下載。在下載前,設定傳輸的類型為二進制文件,并且指定本地要保存的路徑。通過調用Get方法,實現文件的下載。下載過程較慢,可以考慮將其放到線程中實現。

  過程說明:

procedure Get(const ASourceFile: string; ADest: TStream; AResume: Boolean); overload;

procedure Get(const ASourceFile: string; const ADestFile: string; const ACanOverwrite: boolean; AResume: Boolean); overload;

  從遠程服務器上獲取文件。

  屬性說明:

const ASourceFile: string

  遠程服務器上的源文件名

const ADestFile: string

  保存到客戶機上的文件名

const ACanOverwrite: boolean = false

  重寫同名文件

AResume: Boolean = false

  是否進行斷點續傳

  示例代碼:

SaveDialog1.FileName := Name;

if SaveDialog1.Execute then begin

SetFunctionButtons(false);

IdFTP1.TransferType := ftBinary;

BytesToTransfer := IdFTP1.Size(Name);



if FileExists(Name) then begin

case MessageDlg('File aready exists. Do you want to resume the download operation?',

mtConfirmation, mbYesNoCancel, 0) of

mrYes: begin

BytesToTransfer := BytesToTransfer - FileSizeByName(Name);

IdFTP1.Get(Name, SaveDialog1.FileName, false, true);

end;

mrNo: begin

IdFTP1.Get(Name, SaveDialog1.FileName, true);

end;

mrCancel: begin

exit;

end;

end;

end

else begin

IdFTP1.Get(Name, SaveDialog1.FileName, false);

end;


  (6)上傳的實現

  上傳的實現與下載類似,通過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;

  上傳文件至服務器

  屬性說明:

const ASourceFile: string

  將要被上傳的文件

const ADestFile: string = ''

  服務器上的目標文件名

const AAppend: boolean = false

  是否繼續上傳

  代碼示例:

if IdFTP1.Connected then begin

if UploadOpenDialog1.Execute then try

IdFTP1.TransferType := ftBinary;

IdFTP1.Put(UploadOpenDialog1.FileName, ExtractFileName(UploadOpenDialog1.FileName));

//可以在此添加改變目錄的代碼;

finally

//完成清除工作

end;

end;

  (7)刪除的實現

  刪除文件使用Delete方法,該方法刪除指定的文件,刪除對象必須為文件。如果要刪除目錄則使用RemoveDir方法。

  過程說明:

procedure Delete(const AFilename: string);

  刪除文件

procedure RemoveDir(const ADirName: string);

  刪除文件夾,根據不同的服務器刪除文件夾有不同的要求。有些服務器不允許刪除非空文件夾,程序員需要添加清空目錄的代碼。

  上述兩個過程的參數均為目標名稱

  代碼示例:

if not IdFTP1.Connected then exit;

Name := IdFTP1.DirectoryListing.Items[iCurrSelect].FileName;

if IdFTP1.DirectoryListing.Items[iCurrSelect].ItemType = ditDirectory then try

idftp1.RemoveDir(Name);

finally

end

else

try

idftp1.Delete(Name);

finally

end;

  (8)后退的實現

  后退在實際上是目錄操作的一種,可以簡單的改變當前目錄為..來實現,也可以通過回到上級目錄來實現。

  (9)取消的實現

  在IdFtp的傳輸過程中,可以隨時使用abort方法取消當前操作。可以的OnWork事件的實現中來確定何時取消操作。

  代碼示例:

//取消按鈕的OnClick響應

procedure TMainForm.AbortButtonClick(Sender: TObject);

begin

AbortTransfer := true;

end;

//IdFTP的OnWork事件響應

procedure TMainForm.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;

const AWorkCount: Integer);

begin

...

if AbortTransfer then IdFTP1.Abort;

AbortTransfer := false;

end;

  (10)斷點續傳的實現

  斷點續傳就是在上傳或下載過程開始時,判斷已經傳輸過的文件是否上傳輸完畢,如果傳輸沒有成功完成,則在上次中斷處繼續進行傳輸工作。實現該功能需要兩個重要的操作,首先是判斷文件的大小信息,其次是在傳輸過程Get和Put中指定上傳的行為。

  判斷服務器上文件的大小使用函數Size(FileName)。在下載過程中,比較本地文件和遠程文件的信息,然后在Get中指定AResume := True即可。而上傳也一樣,指定Put的AAppend := True就可以了。

  在前面我們講過,Indy的網絡操作大部分是阻塞模式的,TIdFtp也不例外。這樣在上述各個操作運行過程的時候用戶界面被暫時凍結,必須要等待調用返回才能繼續用戶操作界面響應。所以在實際編程中,需要使用多線程的方式來保證戶界面的響應。Windows系統可以使用CreateThread系統調用來創建線程,但是在使用的時候需要開發人員做很多額外的工作來保證線程的同步等問題。而Indy中也包含了實現多線程的控件TIdThreadComponent,相對比之下該控件實現多線程時更加方便,也更容易控制。


主站蜘蛛池模板: 一级做a爰片久久毛片毛片 一级做a爰片久久毛片看看 | 小小的日本在线观看中文 | 青青热在线观看视频精品 | 日韩毛片免费在线观看 | 亚洲日本在线免费观看 | 亚洲大片免费观看 | 青娱乐免费在线观看 | 日韩一区二三区国产好的精华液 | 欧美特黄a级高清免费看片 欧美特黄a级高清免费大片 | 欧美一级特黄一片免费 | 日本a级网站| 亚洲综合专区 | 色天使网| 日本特黄特色aaa大片免费欧 | 亚洲最大的成人网 | 色天天综合网色鬼综合 | 在线视频中文字幕 | 特级毛片黑人三人共一女 | 欧美综合图区亚欧综合图区 | 欧美一级黄色片视频 | 色花堂国产精品首页第一页 | 特黄特色一级特色大片中文 | 亚欧色视频在线观看免费 | 午夜爽视频 | 色婷婷一区二区三区四区成人 | 欧美淫片 | 日韩不卡手机视频在线观看 | 日本高清一区二区三区水蜜桃 | 亚洲 欧美 中文 日韩欧美 | 最新韩国伦理片大全手机在线播放 | 全免费午夜一级毛片一级毛 | 中文字幕视频一区二区 | 最好免费高清视频观看韩国 | 日韩欧美视频在线一区二区 | 图片区欧美色图 | 青青草视频在线免费观看 | 天天摸日日添狠狠添婷婷 | 自拍一区在线 | 日产一区二区三区 | 日韩a级片在线观看 | 中文字幕日韩精品一区口 |