3

I have a question about Uploading to a FTP with C#.

What I want to do is if the file exists then I want to add like Copy or a 1 after the filename so it doesn't replace the file. Any Ideas?

var request = (FtpWebRequest)WebRequest.Create(""+destination+file);
request.Credentials = new NetworkCredential("", "");
request.Method = WebRequestMethods.Ftp.GetFileSize;

try
{
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
    FtpWebResponse response = (FtpWebResponse)ex.Response;
    if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
    {

    }
}
Alessandro Da Rugna
  • 4,571
  • 20
  • 40
  • 64
Johan Beillon
  • 33
  • 1
  • 1
  • 4
  • What part are you having trouble with? It looks like you already have most of the code in place. – Justin Mar 15 '11 at 15:06

4 Answers4

5

It's not particularly elegant as I just threw it together, but I guess this is pretty much what you need?

You just want to keep trying your requests until you get a "ActionNotTakenFileUnavailable", so you know your filename is good, then just upload it.

        string destination = "ftp://something.com/";
        string file = "test.jpg";
        string extention = Path.GetExtension(file);
        string fileName = file.Remove(file.Length - extention.Length);
        string fileNameCopy = fileName;
        int attempt = 1;

        while (!CheckFileExists(GetRequest(destination + "//" + fileNameCopy + extention)))
        {
            fileNameCopy = fileName + " (" + attempt.ToString() + ")";
            attempt++;
        }

        // do your upload, we've got a name that's OK
    }

    private static FtpWebRequest GetRequest(string uriString)
    {
        var request = (FtpWebRequest)WebRequest.Create(uriString);
        request.Credentials = new NetworkCredential("", "");
        request.Method = WebRequestMethods.Ftp.GetFileSize;

        return request;
    }

    private static bool checkFileExists(WebRequest request)
    {
        try
        {
            request.GetResponse();
            return true;
        }
        catch
        {
            return false;
        }
    }

Edit: Updated so this will work for any type of web request and is a little slimmer.

Joshua G
  • 2,086
  • 3
  • 19
  • 22
Jonathan
  • 420
  • 3
  • 13
2

Since FTP control protocol is slow in nature (send-receive) I suggest first pulling directory content and checking against it before uploading the file. Note that dir can return two different standards: dos and unix

Alternatively you can use the MDTM file command to check if file already exist (used to retrieve timestamp of a file).

Tedd Hansen
  • 12,074
  • 14
  • 61
  • 97
0

I am working on something similar. My problem was that:

request.Method = WebRequestMethods.Ftp.GetFileSize;

was not really working. Sometimes it gave exception sometimes it didn't. And for the same file! Have no idea why.

I change it as Tedd said (thank you, btw) to

request.Method = WebRequestMethods.Ftp.GetDateTimestamp;

and it seems to work now.

Zsolt
  • 1
  • 1
  • 1
    If you have a new question, please ask it by clicking the [Ask Question](http://stackoverflow.com/questions/ask) button. Include a link to this question if it helps provide context. – Søren Debois Apr 03 '14 at 07:40
  • I do not have a any questions. I just pointed out that the code that he wrote it's the same as what I am using but for me it wasn't really working because of the "GetFileSize". I solved it by checking the 'timestamp of the file' instead and it seems to work now. I wrote it here because I got the idea from Tedd and thought maybe others can benefit from it. LOL – Zsolt Apr 03 '14 at 08:13
0

There is no shortcut. You need to dir the target directory then use # to determine which name you want to use.

Servy
  • 202,030
  • 26
  • 332
  • 449
nonocast
  • 517
  • 4
  • 14