Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
739 views
in Technique[技术] by (71.8m points)

.net - Recursive upload to FTP server in C#

I would need to upload a folder (which contains sub folders and files) from one server to another from C# code. I have done few research and found that we can achieve this using FTP. But with that I am able to move only files and not the entire folder. Any help here is appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The FtpWebRequest (nor any other FTP client in .NET framework) indeed does not have any explicit support for recursive file operations (including uploads). You have to implement the recursion yourself:

  • List the local directory
  • Iterate the entries, uploading files and recursing into subdirectories (listing them again, etc.)
void UploadFtpDirectory(string sourcePath, string url, NetworkCredential credentials)
{
    IEnumerable<string> files = Directory.EnumerateFiles(sourcePath);
    foreach (string file in files)
    {
        using (WebClient client = new WebClient())
        {
            Console.WriteLine($"Uploading {file}");
            client.Credentials = credentials;
            client.UploadFile(url + Path.GetFileName(file), file);
        }
    }

    IEnumerable<string> directories = Directory.EnumerateDirectories(sourcePath);
    foreach (string directory in directories)
    {
        string name = Path.GetFileName(directory);
        string directoryUrl = url + name;

        try
        {
            Console.WriteLine($"Creating {name}");
            FtpWebRequest requestDir = (FtpWebRequest)WebRequest.Create(directoryUrl);
            requestDir.Method = WebRequestMethods.Ftp.MakeDirectory;
            requestDir.Credentials = credentials;
            requestDir.GetResponse().Close();
        }
        catch (WebException ex)
        {
            FtpWebResponse response = (FtpWebResponse)ex.Response;
            if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
            {
                // probably exists already
            }
            else
            {
                throw;
            }
        }

        UploadFtpDirectory(directory, directoryUrl + "/", credentials);
    }
}

For the background of complicated code around creating the folders, see:
How to check if an FTP directory exists

Use the function like:

string sourcePath = @"C:sourcelocalpath";
// root path must exist
string url = "ftp://ftp.example.com/target/remote/path/";
NetworkCredential credentials = new NetworkCredential("username", "password");

UploadFtpDirectory(sourcePath, url, credentials);

A simpler variant, if you do not need a recursive upload:
Upload directory of files to FTP server using WebClient


Or use FTP library that can do the recursion on its own.

For example with WinSCP .NET assembly you can upload whole directory with a single call to the Session.PutFilesToDirectory:

// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "ftp.example.com",
    UserName = "username",
    Password = "password",
};

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    // Download files
    session.PutFilesToDirectory(@"C:sourcelocalpath", "/target/remote/path").Check();
}

The Session.PutFilesToDirectory method is recursive by default.

(I'm the author of WinSCP)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...