c# - 从给定的 FTP 路径递归删除所有文件和文件夹

标签 c# ftp

我正在尝试创建一个程序,它将递归地删除给定 FTP 路径中的所有文件和文件夹。如果给定路径中只有几个文件或目录,我的程序运行良好。但出于某种原因,如果一个目录中有多个文件,它只会卡在 ReadLine() 行上,最终会出现 IO 错误。这是我的代码:

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;
    }
}

这是我的简单容器 FileObject 类:

internal class FileObject
{
    public bool IsDirectory { get; set; }
    public string FileName { get; set; }
}

最佳答案

我的问题似乎已通过使用主动模式而不是被动模式得到解决。我将此添加到我的代码中:

request.UsePassive = false;

这似乎解决了我的问题。我在包含大量子目录和子子目录的大量文件上测试了它,现在它似乎可以正常工作。

关于c# - 从给定的 FTP 路径递归删除所有文件和文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26919104/

相关文章:

c# - 将控制台输出写入文件

c# - 无法在 nvarchar 上调用方法

c# - 获取SignalR客户端的返回值

c# - 如何在断开连接的情况下自动恢复下载 FTP 文件

php - 如何错误处理 PHP 中的 FTP 函数

.net - .NET 的 FTP 客户端类

c# - 错误 : "Cannot modify the return value" c#

c# - 错误处理代码性能

batch-file - 从FTP服务器下载最新文件的批处理文件

javascript - Node js、PromiseFtp。如何下载目录中的所有文件然后从ftp中删除它们