Ftp receive non existing host file creates empty local file

0 votes
asked Mar 2 by rexh (250 points)

If the file trying to FTP receive does not exist, an error is returned but an empty local file is also created which I don't think should happen.

Applies to: Rebex FTP/SSL

1 Answer

0 votes
answered Mar 4 by Lukas Matyska (52,730 points)
selected Mar 5 by rexh
 
Best answer

This is the "Chicken-and-egg" problem:

Local file preference:

  • Create local file then start downloading.
  • If remote file is not accessible, we ended with empty local file.

Remote file preference:

  • Start file download. When the first byte (or EOF) is received, create local file to store the data.
  • If local file cannot be created, we have to abort FTP transfer, which cannot be done (at all or easily) on some servers.

We think that the problem is not just about deleting an empty local file. The "remote file doesn't exist" is only one of the possible errors.

  • What do you want to do in case that couple of bytes are received?
    Do you want to delete the unfinished file, or do you want to keep the file, so you can resume download after while?

  • What do you want to do in case you are overwriting an existing local file? Would you like to delete the empty file, which means the previously existing file disappears; or do you want to restore the original file (this requires moving files from/to temporary location or using a naming convention).

We leave this questions on application programmer. The application knows what to do in current state. The component behavior is consistent. When download is started the local file is created. When any error arises the local file is kept in its current state (empty or not).

If you want to fully control creating of local files, you can use Stream overload ftp.GetFile("path", outputStream) and handle file creations by yourself.

Or simply delete the file in your preferred cases when an error occurs:

try
{
    ftp.GetFile("remotePath", "localPath");
}
catch (FtpException)
{
    // your condition e.g.:
    // - local file is empty
    // - remote file does not exist
    // - local file did not exist before
    if (condition)
        File.Delete("localPath");
}

The other common solution is to download files to specially named files, e.g. "myfile.txt.ftpdown" or special locations e.g. "c:/temp/ftpdownloads".

  • When the file download is finished the file is moved/renamed to final location e.g. "myfile.txt.ftpdown" -> "myfile.txt"
  • If the file download is aborted for any reason, the file remains as is, indicating the user that it was not finished correctly, and the user will decide for himself what to do (the application keeps simple = do nothing special).

As you can imagine there is a lot of cases and lot of possible solutions. Deleting the empty file after failed transfer is not general solution (and can be a problem in some cases).

Conclusion:
We will keep the current behavior. It is consistent and straightforward.
However, you can vote for adding an option, which will add the requested behavior at https://rebex.uservoice.com

commented Mar 5 by rexh (250 points)
Lukas,
Thank you very much for the very detail explanation and suggestions!
...