从远程FTP下载文件列表

3

我在使用TidFTP组件时遇到了问题。

我能够使用如下代码连接到服务器

vFileList := TStringList.Create;
oClientFTP := TidFTP.Create(nil);
oClientFTP.Port := PortFTP;
oClientFTP.Host := IPHost;
oClientFTP.UserName := UserFTP;
oClientFTP.Password := PasswordFTP;

从StringList获取多个文件后(该列表正好有778个元素),当检索到第137个元素时,会引发异常EIdAcceptTimeout,并显示“Accept timed out.”消息。

我运行的代码如下(顺便说一下,这是在一个线程中运行的)

procedure TDownloadFTP.Get;
begin
try
  for I := 0 to vFileList .Count - 1 do
  begin
    sFileName:= vFileList [I];
    posPoint := LastDelimiter('.', sFileName);
    if posPoint = 0 then
      ForceDirectories(ExtractFilePath(Application.ExeName) + '/BackUp/' + sFileName)
    else
      try
        oClienteFTP.Get(sFileName,IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName) + '/BackUp/') + sFileName, True);
    except

      on E: EIdReplyRFCError do
      begin
      end;
      on E: Exception do
        exceptionList.Add(sFileName);
  end;
end;

在发生异常后,文件会被正确下载,但是每个文件的处理过程需要约25秒时间(我正在下载2KB的PNG图像)。

你对这个异常的含义有任何想法吗?

谢谢


超时是TCP/IP网络中的标准概念。你真的在问什么是TCP超时吗?在FTP连接的上下文中,接受应该从服务器端返回,但却没有返回。现在由你决定如何处理。放弃整个操作、跳过该文件并尝试获取下一个文件、重试该文件3次然后进入下一个文件。你做决定。这个FTP组件只是文件传输解决方案中的一级,当网络故障时它不会为你做出决策,而网络故障总是可能发生的。 - Warren P
2个回答

9

在谷歌搜索EIdAcceptTimeout会导致在Indy论坛中出现这个讨论:

在TIdFTP(客户端)中使用HOST => EIdAcceptTimeout

Remy Lebeau在其中表示:

数据传输期间唯一可能发生该异常的情况是,如果您将TIdFTP.Passive属性设置为False,则FTP服务器会向TIdFTP进行入站连接。那些连接通常被不了解FTP的防火墙/路由器所阻止。当您在防火墙/路由器后时,通常必须将TIdFTP.Passive=True设置为True。

因此,解决方案可能是添加一行代码:

oClientFTP.Passive := True;

顺便提一下,在您的代码片段中,您同时使用了 oClientFTP 和 oClienteFTP。如有需要,请调整我的建议。

4
我再怎么说也说不过你了 :) - Remy Lebeau

1

我本来会将这些内容写成注释,而不是答案,但是注释的限制太大了。如果我有任何不当行为,请告诉我并请原谅。

第二次查看您的代码时,我有几个问题。我看到StringList既可以包含文件(posPoint <> 0),也可以包含目录(posPoint = 0)。第137个元素是文件还是目录?如果是文件,它是新目录后的第一个文件吗?

StringList中的条目是否包括在'\backup\'之后应该有的路径?

假设您的应用程序是Windows应用程序(因为您没有说明其他情况),那么在创建新路径时,为什么要使用正斜杠(/)而不是反斜杠()作为Windows上的路径分隔符?您的代码甚至会在Windows上创建子目录吗?嗯,或许跨平台的Delphi会根据操作系统进行调整。

在oClienteFTP.Get语句中,即使您已经在'/backup/'中有一个斜杠作为尾部分隔符,您仍然说IncludeTrailingPathDelimiter。

您不应再使用'ExtractFilePath(Application.ExeName)'和子目录来存储数据文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接