Recursively delete all files and folders from a specific FTP path
I am trying to create a program that will recursively delete all files and folders from a specific FTP path. My program works well if there are only a few files or directories in the given path. For some reason, even though there are multiple files in the directory, it just hangs at the line ReadLine()
and ends up getting an I / O error. Here is my code:
class Program
{
private const string FtpSite = "myftpsite.com";
private const string FtpUserName = "myusername";
private const string FtpPassword = "mypassword";
static void Main(string[] args)
{
DeleteFilesAndFolders("/");
}
private static void DeleteFilesAndFolders(string path)
{
if (path != null && (path.StartsWith(@"\\") || path.StartsWith("//")))
path = path.Remove(0, 1);
List<FileObject> files = DirectoryListing(path);
foreach (FileObject file in files.Where(file => !file.IsDirectory))
{
DeleteFile(path, file.FileName);
}
foreach (FileObject file in files.Where(file => file.IsDirectory))
{
DeleteFilesAndFolders(path + "/" + file.FileName);
DeleteFolder(path + "/" + file.FileName);
}
}
private static void DeleteFile(string path, string file)
{
var clsRequest = (FtpWebRequest)WebRequest.Create("ftp://" + FtpSite + path + "/" + file);
clsRequest.Credentials = new NetworkCredential(FtpUserName, FtpPassword);
clsRequest.Method = WebRequestMethods.Ftp.DeleteFile;
using (var response = (FtpWebResponse) clsRequest.GetResponse())
{
using (Stream datastream = response.GetResponseStream())
{
if (datastream == null)
return;
using (var sr = new StreamReader(datastream))
{
sr.ReadToEnd();
sr.Close();
}
datastream.Close();
response.Close();
}
}
}
private static void DeleteFolder(string path)
{
var clsRequest = (FtpWebRequest)WebRequest.Create("ftp://" + FtpSite + path);
clsRequest.Credentials = new NetworkCredential(FtpUserName, FtpPassword);
clsRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
using (var response = (FtpWebResponse)clsRequest.GetResponse())
{
using (Stream datastream = response.GetResponseStream())
{
if (datastream == null)
return;
using (var sr = new StreamReader(datastream))
{
sr.ReadToEnd();
sr.Close();
}
datastream.Close();
response.Close();
}
}
}
private static List<FileObject> DirectoryListing(string path)
{
var regex = new Regex(@"^([d-])([rwxt-]{3}){3}\s+\d{1,}\s+.*?(\d{1,})\s+(\w+\s+\d{1,2}\s+(?:\d{4})?)(\d{1,2}:\d{2})?\s+(.+?)\s?$",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
var request = (FtpWebRequest)WebRequest.Create("ftp://" + FtpSite + path);
request.Credentials = new NetworkCredential(FtpUserName, FtpPassword);
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
var result = new List<FileObject>();
using (var response = (FtpWebResponse) request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream == null)
return null;
using (var reader = new StreamReader(responseStream))
{
while (!reader.EndOfStream)
{
string r = reader.ReadLine();
if (string.IsNullOrWhiteSpace(r))
continue;
var reg = regex.Match(r);
var c = new FileObject
{
FileName = reg.Groups[6].Value,
IsDirectory = reg.Groups[1].Value.ToLower() == "d"
};
result.Add(c);
}
reader.Close();
}
response.Close();
}
}
return result;
}
}
And this is my simple container of the FileObject class:
internal class FileObject
{
public bool IsDirectory { get; set; }
public string FileName { get; set; }
}
+3
source to share
1 answer