我正在使用Indy IDFTP创建目录。我需要找到一种可靠的方法来确定目录是否存在以及是否不存在,以调用MakeDir。我尝试了以下代码,但调用List时未发生异常,因此即使该目录当时不存在,也不执行MakeDir。如何确定目录是否存在并创建目录(如果不存在)?

{ Check to see if the '/public_html/XXX/' + iDomain + 'Thumbnails' directory exists }
    try
      IdFTP1.List(nil, '/public_html/XXX/' + iDomain + 'Thumbnails', False);
    except
      on e: EIdReplyRFCError do
      begin
        { '/public_html/XXX/' + iDomain + 'Thumbnails' directory does not exist }
        StatusBar1.SimpleText := 'Making thumbnail directory...';
        StatusBar1.Update;
        iFolder := '/public_html/XXX/' + iDomain;
        { Change directory to /public_html/XXX/iDomain }
        IdFTP1.ChangeDir(iFolder);
        iFolder := 'Thumbnails';
        { Create FTP Directory for Thumbnails }
        IdFTP1.MakeDir(iFolder);
      end;
    end;


在测试期间,该目录不存在,但在运行时e为零?我的方法正确吗?

最佳答案

如果TIdFTP.List()没有引发异常,则FTP服务器很可能返回450答复代码,这仅表示“未执行请求的文件操作”。 TIdFTP.InternalGet()(由TIdFTP.List()TIdFTP.ExtListDir()TIdFTP.Get()使用)不会将450视为错误条件,因为某些服务器(例如Ericsson Switch FTP)在列出以下内容时会发送450一个空的目录,但不存在,因此没有要发送的列表数据。但是,某些服务器在请求的目录不存在时会发送450TIdFTP.List()不会尝试区分。但是,如果TIdFTP.List()没有引发异常,则可以查看TIdFTP.LastCmdResult属性以根据需要手动进行区分。

另外,您不能仅仅依靠引发异常的事实来表示该文件夹不存在。可能发生任何数量的错误。您必须实际查看错误并采取相应措施,例如:

var
  Exists: Boolean;

try
  IdFTP1.List(nil, '/public_html/XXX/' + iDomain + 'Thumbnails', False);
  Exists := True;
  if IdFTP1.LastCmdResult.NumericCode = 450 then
  begin
    if (IdFTP1.LastCmdResult.Text.Text has a message like 'No such file or directory' or similar) then begin
      Exists := False;
    end;
    // look for other possible text messages...
  end;
except
  on e: EIdReplyRFCError do
  begin
    if (e.ErrorCode <> 550) or (e.Message does not have a message like 'Directory not found' or similar) then begin
      raise;
    end;
    Exists := false;
  end;
end;

if not Exists then
begin
  { '/public_html/XXX/' + iDomain + 'Thumbnails' directory does not exist }
  StatusBar1.SimpleText := 'Making thumbnail directory...';
  StatusBar1.Update;
  iFolder := '/public_html/XXX/' + iDomain;
  { Change directory to /public_html/XXX/iDomain }
  IdFTP1.ChangeDir(iFolder);
  iFolder := 'Thumbnails';
  { Create FTP Directory for Thumbnails }
  IdFTP1.MakeDir(iFolder);
end;


更好的方法是:


ChangeDir()直接转到目标目录,看看是否失败。如果是这样,请开始向后浏览路径,对每个父目录调用ChangeDir()直到最终成功,然后根据需要使用MakeDir()ChangeDir()创建路径以返回丢失的子目录。
从路径中的第一个目录开始,然后为ChangeDir(),然后为List(),以查看是否存在下一个子文件夹,如果需要,则为MakeDir(),然后为ChangeDir(),并根据需要重复直到您到达目标目录。


欢迎使用FTP。它不是用于目录管理的非常有效的协议。

10-05 22:28