70

What's an easy way to create a directory on an FTP server using C#?

I figured out how to upload a file to an already existing folder like this:

using (WebClient webClient = new WebClient())
{
    string filePath = "d:/users/abrien/file.txt";
    webClient.UploadFile("ftp://10.128.101.78/users/file.txt", filePath);
}

However, if I want to upload to users/abrien, I get a WebException saying the file is unavailable. I assume this is because I need to create the new folder before uploading my file, but WebClient doesn't seem to have any methods to accomplish that.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Anthony Brien
  • 6,106
  • 7
  • 43
  • 56

5 Answers5

114

Use FtpWebRequest, with a method of WebRequestMethods.Ftp.MakeDirectory.

For example:

using System;
using System.Net;

class Test
{
    static void Main()
    {
        WebRequest request = WebRequest.Create("ftp://host.com/directory");
        request.Method = WebRequestMethods.Ftp.MakeDirectory;
        request.Credentials = new NetworkCredential("user", "pass");
        using (var resp = (FtpWebResponse) request.GetResponse())
        {
            Console.WriteLine(resp.StatusCode);
        }
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Any ideas on how to do this through an HTTP proxy? (not supported by FtpWebRequest) – Jonas Elfström Jun 02 '09 at 13:58
  • Not really, I'm afraid. From what I remember of my days working on HTTP proxies, they translate HTTP methods into FTP commands - and I can't think of an equivalent HTTP method :( – Jon Skeet Jun 02 '09 at 14:01
  • 15
    Is it possible to create nested directories with one WebRequest? I am trying to make "ftp://host.com/ExistingFolder/new1/new2", but I am getting "WebException - 550" (File not found, no access) and don't know weather this is the reason. – David Božjak Jan 25 '10 at 17:37
  • What is the expected (success) response on this? The documentation doesn't seem to cover it. Attempting to create a directory that already exists is giving ma a `550` as mentioned above (in addition to throwing an exception) – jocull Jan 22 '15 at 19:13
42

Here is the answer if you want to create nested directories

There is no clean way to check if a folder exist on the ftp so you have to loop and create all the nested structure one folder at the time

public static void MakeFTPDir(string ftpAddress, string pathToCreate, string login, string password, byte[] fileContents, string ftpProxy = null)
    {
        FtpWebRequest reqFTP = null;
        Stream ftpStream = null;

        string[] subDirs = pathToCreate.Split('/');

        string currentDir = string.Format("ftp://{0}", ftpAddress);

        foreach (string subDir in subDirs)
        {
            try
            {
                currentDir = currentDir + "/" + subDir;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(currentDir);
                reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(login, password);
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                ftpStream = response.GetResponseStream();
                ftpStream.Close();
                response.Close();
            }
            catch (Exception ex)
            {
                //directory already exist I know that is weak but there is no way to check if a folder exist on ftp...
            }
        }
    }
Yannick Richard
  • 1,219
  • 15
  • 25
  • What last two parameters doing? These ain't used in the method body. I used the method without the last two parameter, but could only manage to create nested directory upto 2 level, after that I got 505 error. – Badhon Jain Feb 23 '16 at 12:36
  • it returns error like : The remote server returned an error: (550) File unavailable (e.g., file not found, no access).Plz Help Me.. – Ghanshyam Lakhani Mar 09 '17 at 07:26
  • 1
    @GhanshyamLakhani looks to me like the file isn't accessible. Have you check directory permission? – Yannick Richard Mar 09 '17 at 19:48
  • 1
    Can't explain how vital this is to me. Kudos! – Prince Tegaton Dec 30 '17 at 07:17
  • 2
    FYI assuming you're using a newer C# version you can do this: catch ( WebException ex ) when ( ex.Response is FtpWebResponse ftpResponse && ftpResponse.StatusDescription.Contains( "File exists" ) ) – KyleP Jan 10 '19 at 15:02
  • 1
    @KyleP: Checking for magic string is dangerous as it depends on the server and the localization. Better use ftpResponse.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable which is the code 550 – TomB Mar 20 '20 at 08:41
20

Something like this:

// remoteUri points out an ftp address ("ftp://server/thefoldertocreate")
WebRequest request = WebRequest.Create(remoteUri);
request.Method = WebRequestMethods.Ftp.MakeDirectory;
WebResponse response = request.GetResponse();

(a bit late. how odd.)

Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
0

FluentFTP (nuget link) will create the subdirectory(ies) for you automatically via the

FluentFTP.FtpClient.CreateDirectoryAsync method
KornMuffin
  • 2,887
  • 3
  • 32
  • 48
-1

Creating an FTP directory might be complicated since you have to check if the destination folder exists or not. You may need to use an FTP library to check and create a directory. You can take a look at this one: http://www.componentpro.com/ftp.net/ and this example: http://www.componentpro.com/doc/ftp/Creating-a-new-directory-Synchronously.htm

Adi Sembiring
  • 5,798
  • 12
  • 58
  • 70