为什么通过FTP传输的文件有时会大小不同或损坏?

4
我在使用Delphi XE2中的TidFTP组件下载文件时遇到了问题。我可以连接到FTP站点,获取文件列表并执行get命令。然而,当我尝试使用get命令下载文件时,文件总是比源文件大。然后随后的文件就会损坏。
此外,如果我尝试下载多个文件,第一个文件会下载(大于源文件),其余文件将被跳过。没有从get命令抛出错误,它只是退出了。我尝试钩入TidFTP控件上的某些事件,例如AfterGet和OnStatus,但一切似乎正常。
我尝试使用第三方FTP客户端访问文件并下载它,以确保它不是我们FTP服务器的问题,该下载按预期工作。所以我想这可能与TidFTP控件有关,或者我做错了什么。
以下是我用来下载文件的例程:
var
  ftp: TIdFTP;
  strDirectory: string;
begin
  ftp := TIdFTP.Create(nil);
  try
    ftp.Host := 'ftp.myftpserver.com'
    ftp.Passive := false;
    ftp.Username := 'TestUser';
    ftp.Password := 'TestPassword';
    ftp.ConnectTimeout := 1000;
    ftp.Connect();
    ftp.BeginWork(wmRead);
    ftp.ChangeDir('/TestArea/');
    strDirectory := 'c:\test\';
    if not DirectoryExists(strDirectory) then
      CreateDir(strDirectory);
    ftp.Get('Test.zip', strDirectory + '\' + 'Test.zip', true, false);
   ftp.Disconnect();
  except
    on e: exception do
      showMessage(e.message);
  end;
end;
1个回答

10

您需要设置TIdFTP.TransferType。它的默认值是Id_TIdFTP_TransferType,即ftASCII。您需要改用ftBinary,并在执行Get之前将其设置:

ftp.Connect();
...
ftp.TransferType := ftBinary;
ftp.Get('Test.zip', strDirectory + '\' + 'Test.zip', true, false);
ftp.Disconnect();

TIdFTP.TransferType 的文档中有一个地方说,当执行 Login 或在设置了 AutoLogin 的情况下调用 Connect 时,它会自动设置为 ftBinary,但是您的代码中没有执行 Login 也没有设置 AutoLogin。紧接在上述语句之后的段落说:

根据下面评论中的 @RemyLebeau 的说法,引用的文档存在错误,TransferType 从未在 Login 中设置为 ftBinary。将删除原有内容以供参考。

根据文档:

TransferType 的默认值是 Id_TIdFTP_TransferType,在组件初始化期间分配给它。


设置ftBinary类型就解决了问题。非常感谢您的帮助和快速回复! - Jeff Cope
2
文档已过时。在“Login()”中从未将“TransferType”设置为“ftBinary”。但是根据RFC 959,“TransferType”默认为“ftASCII”。您可以在调用“Connect()”后设置“TransferType”。在每次调用“Get()”或“Put()”之前设置“TransferType”是一个好习惯。 - Remy Lebeau
@Remy: 我会修改以确保这一点显而易见。您能确保留下您的评论以供参考吗? - Ken White

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