首页 > 其他分享 >Indy实现FTP客户端

Indy实现FTP客户端

时间:2023-03-06 22:03:32浏览次数:33  
标签:FTP begin end Indy DirectoryListBox const IdFTP 客户端

首先大家了解一下FTP的基本知识:FTP是一个标准协议,它是在计算机和网络之间交换文件的最简单的方法。

FTP也是应用TCP/IP协议的应用协议标准。

FTP通常于将作者的文件上传至服务器,或从服务器上下传文件的一种普遍的使用方式作为用户,您可以用非常简单的DOS界面来使用FTP,也可以使用由第三方提供的软件(如FLASHFXP)来对服务器的数据进行删除,重命名等操作。

当然,使用这些之前,必须先要登录服务器,用指定的用户名和密码或匿名(Anonymous)登录。  

这些大家都知道,不过还是讲一下。用DOS操作FTP我不讲了。我今天主要用INDY组件里的IDFTP控件做一FTP客户端软件(非常简单 )

我现在讲一下IDFTP控件的几个属性如下:

Host:FTP服务器地址。

USER:用户帐号。

Password:密码。

Passive:用于控制FTP数据连接方法。FTP的数据传输可以有主动和被动。

PORT是主动模式,在建立数据通道时,服务端去连接别人;

PASV是被动模式,在建立数据通道时,服务端被别人连接;

建立数据通道时,用PORT模式还是PASV模式,选择权在于FTP客户端。

IDFTP里的passive是一个Boolean数据类型。当True时为主动;当false时为被动。

Port:FTP服务的默认端口是21。

TransferType:传输文件的类型,可以取值为FtBinary(8位的任意文件)和FtAscii(7位的文本文件)。

SystemDesc:FTP服务器的描述。  

IDFTP的几个方法

常用的方法有以下几个:

Connect:连接FTP服务器.

Abort:停止FTP服务的操作。

Quit:关闭客户端与服务器的连接.

Noop:用于保持连接的命令,防止被服务器关掉连接.

List:获取FTP服务器上的文件和目录列表.

原型为

procedure List(ADest:TStrings;Const ASpecifier:String;const ADetails:Boolean);

RetrieveCurrentDir:取得当前目录的名称.

Site:发送FTP服务器的命令.

原型为:

procedure Site(const ACommand:string);

ChangeDir:改变FTP服务器上的当前目录

原型为: procedure ChangeDir(const ADirName:string);

ChangeDirUp:将FTP服务器上的目录返回到你目录.

温州-Dillon(86695893) 13:08:26

MakeDir:在服务器上建立一个新目录.

原型为:

procedure MakeDir(const ADirName:String);

RemoveDir:删除服务器上的一个目录.

原型为:

procedure RemoveDir(const ADirName:string);

Get:从FTP服务器上下载文件.这个方法被重载了.

原型为:

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

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

Put:用于向服务器上传文件.该方法被重载.

原型为:

procedure Put(const ASourceFile:TStream;const ADest:string;const Appand:Boolean);overload;

procedure Put(const ASourceFile:string;const ADest:string;const AAppand:Boolean);overload;

KillDataChannal:关闭FTP数据通道.

所谓“重载”,就是当从多个“类”身上继承一些方法时,会发生冲突。为了避免这一个冲突,就使用了“重载”功能

Delete:删除FTP服务器上一个文件.

原形为:procedure Delete(const AfileName:string);

Rename:更改服务器上的文件名.

原型为:

procedure Rename(const ASourceFile:string;const ADestFile:string);

Size:获取文件大小信息.

原型为:

function Size(const AFileName:string):Integer;  

当大家装好INDY9.0 附带一个例程,在INDY\FTPDEMO下可以找到.

是一个不错的DEMO

我仿造这个DEMO做的一个例子。里面包含详细的注释。

当然,还要讲一下,做FTP客户端的心得哦

我现在,慢慢把里面的代码发了来做一下讲解

首先是登录按钮里的代码:

还是先给大家看一下这个界面吧

Delete:删除FTP服务器上一个文件.

原形为:procedure Delete(const AfileName:string);

Rename:更改服务器上的文件名.

原型为:

procedure Rename(const ASourceFile:string;const ADestFile:string);

Size:获取文件大小信息.

原型为:

function Size(const AFileName:string):Integer;

begin

ftpcon.Enabled:=false;

//-----------------连接FTP服务器------------------//

with idftp do

      begin

      try

      Host:=trim(edit1.Text);       //FTP服务器IP地址

      Username:=trim(edit2.Text); //用户名

      Password:=trim(edit3.Text); //密码

      Connect;    // 连接

      DirectoryListBox.Items.Clear;    // 清空目录以及文件信息

      DebugListBox.Items.Clear;    // 清空记录信息

     // SaveFTPHostInfo(trim(CURDIR.Text), 'FTPHOST');

      finally

      if Connected then

          begin

           DisplayDir(trim(CURDIR.Text)); // 改变当前路径

           FTPCon.Enabled:=false;     // 连接按钮

           FTPDisCon.Enabled:=True; // 断开按钮

          end;

      end;

      end;

end;

断开按钮的代码:

begin

try

    if IdFTP.Connected then     // 判断客户端是否连着服务器

       IdFTP.Abort;

    if TransferrignData then    // 判断客户端与服务器之间是否有数据传输

       IdFTP.Quit;

finally

    IdFTP.Disconnect;    // 断开连接

    FTPCon.Enabled:=true;

    FTPDisCon.Enabled:=false;

end;

end;

TransferrignData变量全局变量里有定义的

连接按钮里的DisplayDir的过程如下:  

procedure TFFTPClient.DisplayDir(DirName: String);

Var

    LS: TStringList;

begin

    LS := TStringList.Create;

    try

      IdFTP.ChangeDir(DirName);

      IdFTP.TransferType:=ftASCII;    // 编译不通过时 USES IdFTPCommon

      CURDIR.Text:= IdFTP.RetrieveCurrentDir;

      DirectoryListBox.Items.Clear;

      IdFTP.List(LS);    // 把IDFTP里的LIST与LS关联起来

      DirectoryListBox.Items.Assign(LS);     // 把DIRECTORYLISTBOX 与 LS 关联起来

      if DirectoryListBox.Items.Count > 0 then

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

    finally

      LS.Free;

    end;

end;

还有一个最重要的一段代码,就是listbox如何显示目录信息的

首先,把LISTBOX的STYLE的属性改成lbOwnerDrawFixed

再在ONDRAWITEM方法里添加如下代码:

procedure TFFTPClient.DirectoryListBoxDrawItem(Control: TWinControl;

    Index: Integer; Rect: TRect; State: TOwnerDrawState);

Var

    R: TRect;

begin

//---------------------------------当选择一条记录时

    if odSelected in State then

    begin  

      DirectoryListBox.Canvas.Brush.Color := $00895F0A;

      DirectoryListBox.Canvas.Font.Color := clWhite;

    end

    else

    begin

      DirectoryListBox.Canvas.Brush.Color := clWindow;

    end;

//---------------------------------显示当前目录里的信息

if Assigned(IdFTP.DirectoryListing) and (IdFTP.DirectoryListing.Count>Index) then

    begin

      DirectoryListBox.Canvas.FillRect(Rect);

      with IdFTP.DirectoryListing.Items[Index] do

        begin

          //------------------------//

          DirectoryListBox.Canvas.TextOut(Rect.Left, Rect.Top, FileName); // 文件名

          R := Rect;

          R.Left := Rect.Left + HeaderControl1.Sections.Items[0].Width;

          //------------------------//

          R.Right := R.Left + HeaderControl1.Sections.Items[1].Width;

          DirectoryListBox.Canvas.FillRect(R);

          DirectoryListBox.Canvas.TextOut(R.Left, Rect.Top, IntToStr(Size)); // 文件大小

          //------------------------//

          R.Left := R.Right;

          R.Right := R.Left + HeaderControl1.Sections.Items[2].Width;

          DirectoryListBox.Canvas.FillRect(R);

          if ItemType = ditDirectory then     // 是文件夹类型    编译不通过时要USES IDFTPLIST

              begin

                DirectoryListBox.Canvas.TextOut(R.Left, Rect.Top, '文件夹');

              end

              else

              begin

                DirectoryListBox.Canvas.TextOut(R.Left, Rect.Top, '文件');

              end;

          //------------------------//

          R.Left := R.Right;

          R.Right := R.Left + HeaderControl1.Sections.Items[3].Width;

          DirectoryListBox.Canvas.FillRect(R);

          DirectoryListBox.Canvas.TextOut(R.Left, Rect.Top, FormatDateTime('yyyy-mm-dd hh:mm', ModifiedDate)); // 修改时间

          //------------------------//

          R.Left := R.Right;

          R.Right := R.Left + HeaderControl1.Sections.Items[4].Width;

          DirectoryListBox.Canvas.FillRect(R);

          DirectoryListBox.Canvas.TextOut(R.Left, Rect.Top, GroupName); // 组名

          //------------------------//

          R.Left := R.Right;

          R.Right := R.Left + HeaderControl1.Sections.Items[5].Width;

          DirectoryListBox.Canvas.FillRect(R);

          DirectoryListBox.Canvas.TextOut(R.Left, Rect.Top, OwnerName);    // 拥有者名字

          //------------------------//

          R.Left := R.Right;

          R.Right := R.Left + HeaderControl1.Sections.Items[6].Width;

          DirectoryListBox.Canvas.FillRect(R);

          DirectoryListBox.Canvas.TextOut(R.Left, Rect.Top, OwnerPermissions + GroupPermissions + UserPermissions);    // 权限

      end;

    end;

end;

这几部分是这软件里的中心

不过,可以通过IDFTP里的work,status,workbegin,workend来实现进度条

还有上传代码:

if IdFTP.Connected then

begin

      if OpenDialog1.Execute then

          try

            IdFTP.TransferType := ftBinary;

            IdFTP.Put(OpenDialog1.FileName, ExtractFileName(OpenDialog1.FileName));

          finally

            DisplayDir(idftp.RetrieveCurrentDir);

          end;

    end;

end;

这段代码,首先要判断IDFTP是否还连着

下传代码如下:

温州-Dillon(86695893) 13:36:23

procedure TFFTPClient.DirectoryListBoxDblClick(Sender: TObject);

Var

    FName: String;

begin

    if not IdFTP.Connected then // 判断FTP是否还连着服务器

        exit;

    FName := IdFTP.DirectoryListing.Items[DirectoryListBox.ItemIndex].FileName;

    if IdFTP.DirectoryListing.Items[DirectoryListBox.ItemIndex].ItemType = ditDirectory then // 假如双击是文件夹,就改变路径

    begin

      CURDIR.Text:=Trim(FName);

      DisplayDir(CURDIR.Text);

    end

    else

    begin

      try

        SaveDialog1.FileName := Name; // 得到保存的文件名

        if SaveDialog1.Execute then

        begin

          IdFTP.TransferType := ftBinary; // 以二进制进行传输

          BytesToTransfer := IdFTP.Size(Name); // 得到文件的大小

          if FileExists(Name) then

              begin

              case MessageDlg('文件已经存在,是否重新下载?',mtConfirmation, mbYesNoCancel, 0) of

                    mrYes:

                    begin

                      BytesToTransfer := BytesToTransfer-FileSizeByName(Name); // FileSizeByName在IdGlobal

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

                    end;

                    mrNo:

                    begin

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

                    end;

                    mrCancel:

                    begin

                      exit;

                    end;

              end;

              end

          else

              begin

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

              end;

        end;

      finally

      end;

    end;

end;

我要直接做在目录列表框的双击方法里的,假如双击文件就下载,文件夹就打开

其它的功能,都是通过IDFTP的方法直接实现的。例如新建目录:

var

    DirName:string;

begin

DirName:=InputBox('输入新目录名称', '提示信息', '');

    if DirName <> '' then

      try

        IdFTP.MakeDir(DirName);

        DisplayDir(CURDIR.Text);

      finally

      end;

end; 

 

标签:FTP,begin,end,Indy,DirectoryListBox,const,IdFTP,客户端
From: https://www.cnblogs.com/sixty-five/p/17185668.html

相关文章

  • FTP文件传输协议 :文件传输结束如何判断
    小结:FTP服务器有两大部分组成:一个主进程,负责接受新的请求;还有若干从属进程,负责处理单个请求。FTP文件传输协议经典问题:文件传输结束如何判断-知识库-新睿云https://......
  • pyftpdlib 中文乱码修复文件
    pyftpdlib1.5.72个文件https://gitee.com/wgf4242/vue3start/raw/vite2tmp/imgs/filesystems.pyhttps://gitee.com/wgf4242/vue3start/raw/vite2t......
  • sftp error: process_write: write failed
    问题描述使用sftp传输东西,结果只传了个空文件过去,内容全无查看messages日志sftp-server[16089]:error:process_write:writefailed原因分析:资源不够用a.ulimit-afile......
  • Canvas、客户端、表单
    Canvasvarcanvas=document.querySelector('.myCanvas');varwidth=canvas.width=window.innerWidth;varheight=canvas.height=window.innerHeight;滚动条......
  • 跨平台`ChatGpt` 客户端
    跨平台ChatGpt客户端一款基于Avalonia实现的跨平台ChatGpt客户端,通过对接ChatGpt官方提供的ChatGpt3.5模型实现聊天对话实现创建ChatGpt的项目名称,项目类型是Avaloni......
  • TCP通信聊天服务端和客户端(C/C++语言开发)附完整源码
    距离上次学Python写的Python实现简单聊天室已经过去好久了,现在学c++又写了一遍,其实过程差不多,无非是语法的变化,目前仅实现最简单的一对一的通信,然后改就是了,接下来应该是......
  • 在vs 启动应用时,提示”需要 Oracle 客户端软件8.1.7或更高版本 “
    解决这个问题,首先应先寻找出现该问题的原因。在一开始我的电脑中已经有免安装的oracle客户端了,可以在pl_sql中使用,但是在vs中是不行的,我又安装了32位的客户端(安装版的)。......
  • ftp服务器搭建
    1.开启服务控制面板--程序--启用或关闭windows功能--找到Internet信息服务,并选中“FTP服务”、“FTP扩展性”和“IIS管理控制台”2.设置站点打开“IIS管理器”--左......
  • EF Core 客户端与服务器评估
    写linq语句时需要比较数据库中的日期和当前日期,写的代码如下vartaskInCount=repository.DbContext.Set<Wms_TaskHistory>().Where(q=>DateTime.Parse(q.CreateDate.......
  • eas里客户端保存,提交的校验方式
    业务单据、基础资料,在编辑界面EditUI中进行必录校验时,可以直接从界面绑定的数据对象editData中获取值,无需通过界面控件取值。对于单据头中的属性值,通过editData可以直接通......