Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are files sometimes a different size or corrupt after transferring by FTP?

I'm having a problem downloading a file using the TidFTP component in Delphi XE2. I am able to get a connection to the FTP site, get a list of files and perform the get command. However, when I try to download a file using the get command the file always downloads larger than the source file. Then the subsequent file is corrupt.

Additionally, if I try to download multiple files, the first file downloads (larger than the source) and the remaining files are skipped. No error is thrown from the get command, it just quits. I tried to hook into some of the events on the TidFTP control like AfterGet and OnStatus but everything appears normal.

I tried using a 3rd party FTP client to access the file and download it just to make sure it was not a problem with our FTP server and that download worked as expected. So I'm thinking it might be related to the TidFTP control or perhaps I'm doing something incorrectly.

Here is the routine I'm using to download the file:

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;
like image 331
Jeff Cope Avatar asked Dec 25 '22 21:12

Jeff Cope


1 Answers

You need to set the TIdFTP.TransferType. Its default value is Id_TIdFTP_TransferType, which is ftASCII. You need to use ftBinary instead, and set it before executing the Get:

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

The documentation for TIdFTP.TransferType says in one place that it's automatically set to ftBinary when Login is executed or when Connect is called when AutoLogin is set to true, but you're not executing Login in your code and haven't set AutoLogin. The paragraph immediately following the above statement says:

According to @RemyLebeau in the comments below, the documentation quoted is in error, and TransferType was never set to ftBinary in Login. Leaving the stricken content for future reference.

According to the documentation:

The default value for TransferType is Id_TIdFTP_TransferType, as assigned during initialization of the component.

like image 163
Ken White Avatar answered Apr 06 '23 01:04

Ken White