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)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…