С# Проверить, СУЩЕСТВУЕТ ли FTP-каталог

У меня есть этот FTP-метод, который проверяет, существует ли каталог. Сначала он работает нормально, но теперь он все еще возвращает true, даже если каталог не существует. Я пробовал много вещей и установил точку останова, чтобы увидеть, какое свойство объекта ответа я могу использовать, чтобы определить, существует ли каталог или нет. Я также искал в Интернете, и решения, похоже, не работают для меня. Вот мой метод FTP.

public bool directoryExists(string directory)
            {
                /* Create an FTP Request */
                ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + directory);
                /* Log in to the FTP Server with the User Name and Password Provided */
                ftpRequest.Credentials = new NetworkCredential(user, pass);
                /* Specify the Type of FTP Request */
                ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                try
                {
                    using (ftpRequest.GetResponse())
                    {
                        return true;
                    }
                    //var response = ftpRequest.GetResponse();
                    //if (response != null)
                    //    return true;
                    //else return false;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    return false;
                }

                /* Resource Cleanup */
                finally
                {
                    ftpRequest = null;
                }
            }

А вот метод, который вызывает его и возвращает true, даже если каталога не существует:

private string getDirectory(ref FtpClass ftp, string internalID)
        {
            string remoteSubPathDel = internalID + "\\trunk\\prod\\xml\\delete";
            string remoteSubPathUpdate = internalID + "\\trunk\\prod\\xml\\update";
            string remoteSubPathNew = internalID + "\\trunk\\prod\\xml\\new";
            if (ftp.directoryExists(remoteSubPathDel))
                return remoteSubPathDel;
            else if (ftp.directoryExists(remoteSubPathUpdate))
                return remoteSubPathUpdate;
            else if (ftp.directoryExists(remoteSubPathNew))
                return remoteSubPathNew;
            else
                return String.Empty;
        }

Надеюсь, кто-то может помочь. Спасибо! :)


person finnTheHumin    schedule 24.05.2013    source источник
comment
Вы столкнетесь с этим с FTP. Информация, возвращаемая FTP-сервером, не определяется RFC, поэтому некоторые клиенты не смогут анализировать ответы.   -  person Spencer Ruport    schedule 24.05.2013


Ответы (3)


У меня есть работа для этой проблемы. Не самый лучший вид, но он работает.

Может быть, это может помочь другим с той же проблемой, что и моя.

public bool directoryExists2(string directory, string mainDirectory)
        {
            try
            {
                var list = this.GetFileList(mainDirectory);
                if (list.Contains(directory))
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

EDIT: я включил метод GetFileList в ответ на комментарий Рэя Чанга.

public string[] GetFileList(string path)
        {
            var ftpPath = host + "/" + path;
            var ftpUser = user;
            var ftpPass = pass;
            var result = new StringBuilder();
            try
            {
                var strLink = ftpPath;
                var reqFtp = (FtpWebRequest)WebRequest.Create(new Uri(strLink));
                reqFtp.UseBinary = true;
                reqFtp.Credentials = new NetworkCredential(ftpUser, ftpPass);
                reqFtp.Method = WebRequestMethods.Ftp.ListDirectory;
                reqFtp.Proxy = null;
                reqFtp.KeepAlive = false;
                reqFtp.UsePassive = true;
                using (var response = reqFtp.GetResponse())
                {
                    using (var reader = new StreamReader(response.GetResponseStream()))
                    {
                        var line = reader.ReadLine();
                        while (line != null)
                        {
                            result.Append(line);
                            result.Append("\n");
                            line = reader.ReadLine();
                        }
                        result.Remove(result.ToString().LastIndexOf('\n'), 1);
                    }
                }
                return result.ToString().Split('\n');
            }
            catch (Exception ex)
            {
                Console.WriteLine("FTP ERROR: ", ex.Message);
                return null;
            }

            finally
            {
                ftpRequest = null;
            }
        }
person finnTheHumin    schedule 24.05.2013
comment
где ваш код метода this.GetFileList? а что такое this? - person Ray Cheng; 12.02.2015
comment
@RayCheng, пожалуйста, смотрите правку выше. это относится к FTPClass.cs, классу, который я создал для FTP-операций. - person finnTheHumin; 12.02.2015
comment
я обнаружил, что некоторым FTP-серверам требуется, чтобы путь заканчивался на /, в противном случае путь будет считаться путем к файлу и будет применяться каталог, прослушивающий уровень выше. - person MiguelSlv; 06.08.2018

Попробуй это:

public bool directoryExists(string directory)
{
    /* Create an FTP Request */
    ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + directory);
    /* Log in to the FTP Server with the User Name and Password Provided */
    ftpRequest.Credentials = new NetworkCredential(user, pass);
    /* Specify the Type of FTP Request */
    ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    try
    {
        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        {
            return true;
        }
    }
    catch (Exception ex)
    {
        return false;
    }

            /* Resource Cleanup */
    finally
    {
        ftpRequest = null;
    }
}

Обратите внимание на эту строку using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())

person lexeRoy    schedule 24.05.2013
comment
Использование исключений, как правило, не является хорошим способом обработки вещей, которые вы ожидаете. Замедляет код. Может быть лучше начать с корня FTP-сервера и выполнять ряд методов ListDirectory, пока вы не подтвердите, что нужный каталог существует. - person mason; 24.05.2013
comment
@mason: Вы думаете, что потенциальный поиск по всему дереву каталогов быстрее, чем использование для этого исключения? Я так не думаю. Если у FtpWebRequest есть метод DirectoryExists(), то это было бы здорово. В противном случае я думаю, что исключение - это логичный подход. - person Jonathan Wood; 22.04.2014
comment
Я использовал аналогичный подход в своих тестах на существование каталога. Однако сегодня этот код не работает. Не удается создать исключение, когда каталог не существует. Я обновился до VS2013. Попытка определить, изменилось ли какое-либо поведение в .NET. - person Jonathan Wood; 22.04.2014
comment
@JonathanWood Исключения предназначены для вещей, которые вы не ожидаете и требуют специальной обработки. Их не следует использовать для чего-то, чего можно ожидать регулярно. См. Рекомендации по работе с исключениями в MSDN. . В методе, который проверяет, существует ли каталог, я думаю, что разумно ожидать, что каталог не будет существовать довольно часто. - person mason; 22.04.2014

In 2021 это работает как на наших Linux, так и на Windows live чтение с ftp-сервера (как на Windows, так и на Linux)

Примечание

  • основная папка на фтп Windows - web
  • основная папка на фтп Linux - public_html

TL;DR;

  • нижняя строка: URL-адрес должен заканчиваться /

Это работает:

ftp://ftp.yourdomain.com.br/public_html/
ftp://ftp.yourdomain.com.br//public_html/
ftp://ftp.yourdomain.com.br/web/
ftp://ftp.yourdomain.com.br//web/

Это не работает:

ftp://ftp.yourdomain.com.br/public_html
ftp://ftp.yourdomain.com.br//public_html
ftp://ftp.yourdomain.com.br/web
ftp://ftp.yourdomain.com.br//web

Использование: //проверка существования каталога public_html

var url = "/public_html/";
var result = FtpUtil.DoesDirectoryExists(url,  "ftp://ftp.yourdomain.com.br", "ftp user here", "ftp password here");

static bool DoesDirectoryExists(string directory, string ftpHost, string ftpUser, string ftpPassword) {
                    FtpWebRequest ftpRequest = null;
                    try {
                            ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + ftpHost + directory));
                            ftpRequest.Credentials = new NetworkCredential(ftpUser, string ftpPassword);
                            ftpRequest.UseBinary = true;// optional
                            ftpRequest.KeepAlive = false;// optional
                            ftpRequest.UsePassive = true;// optional
                            ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
        
                            using (FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse()) {
                                return true;//directory found
                            }
                    }
                    catch (WebException ex) {
                            if (ex.Response != null) {
                                FtpWebResponse response = (FtpWebResponse)ex.Response;
                                if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
                                    return false;// directory not found.  
                            }
                            return false; // directory not found.
                    }
                    finally {
                        ftpRequest = null;
                    }
        }
person Wander    schedule 21.06.2021