Как проверить, существует ли каталог FTP - PullRequest
29 голосов
/ 05 мая 2010

В поисках лучшего способа проверить данный каталог по FTP.

В настоящее время у меня есть следующий код:

private bool FtpDirectoryExists(string directory, string username, string password)
{

    try
    {
        var request = (FtpWebRequest)WebRequest.Create(directory);
        request.Credentials = new NetworkCredential(username, password);
        request.Method = WebRequestMethods.Ftp.GetDateTimestamp;

        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    }
    catch (WebException ex)
    {
        FtpWebResponse response = (FtpWebResponse)ex.Response;
        if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
            return false;
        else
            return true;
    }
    return true;
}

Возвращает false независимо от того, существует каталог или нет. Может кто-нибудь направить меня в правильном направлении.

Ответы [ 10 ]

18 голосов
/ 08 мая 2010

По сути, в ловушке ошибка, которую я получаю при создании каталога, как это.

private bool CreateFTPDirectory(string directory) {

    try
    {
        //create the directory
        FtpWebRequest requestDir = (FtpWebRequest)FtpWebRequest.Create(new Uri(directory));
        requestDir.Method = WebRequestMethods.Ftp.MakeDirectory;
        requestDir.Credentials = new NetworkCredential("username", "password");
        requestDir.UsePassive = true;
        requestDir.UseBinary = true;
        requestDir.KeepAlive = false;
        FtpWebResponse response = (FtpWebResponse)requestDir.GetResponse();
        Stream ftpStream = response.GetResponseStream();

        ftpStream.Close();
        response.Close();

        return true;
    }
    catch (WebException ex)
    {
        FtpWebResponse response = (FtpWebResponse)ex.Response;
        if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
        {
            response.Close();
            return true;
        }
        else
        {
            response.Close();
            return false;
        }  
    }
}
8 голосов
/ 05 июня 2014

Я тоже застрял с подобной проблемой. Я использовал,

FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftpserver.com/rootdir/test_if_exist_directory");  
request.Method = WebRequestMethods.Ftp.ListDirectory;  
FtpWebResponse response = (FtpWebResponse)request.GetResponse();

и ожидал исключения в случае, если каталог не существует. Этот метод не выбрасывал исключение.

После нескольких попыток я изменил каталог с: " ftp: //ftpserver.com/rootdir/test_if_exist_directory" to: " ftp: //ftpserver.com/rootdir/test_if_exist_directory/". Теперь этот кусок работает на меня.

Я думаю, что мы должны добавить обратную косую черту (/) в URI папки ftp, чтобы получить эту работу.

По запросу, полное решение теперь будет:

public bool DoesFtpDirectoryExist(string dirPath)
{
    try
    {
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(dirPath);  
        request.Method = WebRequestMethods.Ftp.ListDirectory;  
        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        return true;
     }
     catch(WebException ex)
     {
         return false;
     }
}

//Calling the method:
string ftpDirectory = "ftp://ftpserver.com/rootdir/test_if_exist_directory/"; //Note: backslash at the last position of the path.
bool dirExists = DoesFtpDirectoryExist(ftpDirectory);
8 голосов
/ 20 августа 2012

Я предполагаю, что вы уже знакомы с FtpWebRequest, поскольку это обычный способ доступа к FTP в .NET.

Вы можете попытаться перечислить каталог и проверить код состояния ошибки.

    try 
{  
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.microsoft.com/12345");  
    request.Method = WebRequestMethods.Ftp.ListDirectory;  
    using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())  
    {  
        // Okay.  
    }  
}  
catch (WebException ex)  
{  
    if (ex.Response != null)  
    {  
        FtpWebResponse response = (FtpWebResponse)ex.Response;  
        if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)  
        {  
            // Directory not found.  
        }  
    }  
} 
6 голосов
/ 17 декабря 2010

Я бы попробовал что-то в этом роде:

  • Отправьте команду MLST FTP (определено в RFC3659) и проанализируйте ее вывод. Он должен вернуть действительную строку с подробностями каталога для существующих каталогов.

  • Если команда MLST недоступна, попробуйте изменить рабочий каталог в проверенный каталог с помощью команды CWD. Не забудьте определить текущий путь (команда PWD) до перехода в проверенный каталог, чтобы иметь возможность вернуться назад.

  • На некоторых серверах комбинация команд MDTM и SIZE может использоваться для аналогичных целей, но поведение довольно сложное и выходит за рамки этого поста.

Это в основном метод DirectoryExists в текущей версии нашего компонента Rebex FTP . Следующий код показывает, как его использовать:

string path = "/path/to/directory";

Rebex.Net.Ftp ftp = new Rebex.Net.Ftp();
ftp.Connect("hostname");
ftp.Login("username","password");

Console.WriteLine(
  "Directory '{0}' exists: {1}", 
  path, 
  ftp.DirectoryExists(path)
);

ftp.Disconnect();
4 голосов
/ 20 июля 2011

Используйте этот код, это может быть ваш ответ ..

 public bool FtpDirectoryExists(string directoryPath, string ftpUser, string ftpPassword)
        {
            bool IsExists = true;
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(directoryPath);
                request.Credentials = new NetworkCredential(ftpUser, ftpPassword);
                request.Method = WebRequestMethods.Ftp.PrintWorkingDirectory;

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                IsExists = false;
            }
            return IsExists;
        }

Я назвал этот метод как:

bool result =    FtpActions.Default.FtpDirectoryExists( @"ftp://mydomain.com/abcdir", txtUsername.Text, txtPassword.Text);

Зачем использовать другую библиотеку - создайте свою собственную логику.

2 голосов
/ 02 ноября 2011

Я пытался получить всестороннюю проверку, но ни методы WebRequestMethods.Ftp.PrintWorkingDirectory, ни WebRequestMethods.Ftp.ListDirectory не будут работать правильно. Они не смогли при проверке на ftp://<website>/Logs, который не существует на сервере, но они говорят, что это делает.

Итак, метод, который я придумал, был попытаться загрузить в папку. Тем не менее, одна проблема - это формат пути, который вы можете прочитать в этой теме Загрузка в Linux

Вот фрагмент кода

private bool DirectoryExists(string d) 
{ 
    bool exists = true; 
    try 
    { 
        string file = "directoryexists.test"; 
        string path = url + homepath + d + "/" + file;
        //eg ftp://website//home/directory1/directoryexists.test
        //Note the double space before the home is not a mistake

        //Try to save to the directory 
        req = (FtpWebRequest)WebRequest.Create(path); 
        req.ConnectionGroupName = "conngroup1"; 
        req.Method = WebRequestMethods.Ftp.UploadFile; 
        if (nc != null) req.Credentials = nc; 
        if (cbSSL.Checked) req.EnableSsl = true; 
        req.Timeout = 10000; 

        byte[] fileContents = System.Text.Encoding.Unicode.GetBytes("SAFE TO DELETE"); 
        req.ContentLength = fileContents.Length; 

        Stream s = req.GetRequestStream(); 
        s.Write(fileContents, 0, fileContents.Length); 
        s.Close(); 

        //Delete file if successful 
        req = (FtpWebRequest)WebRequest.Create(path); 
        req.ConnectionGroupName = "conngroup1"; 
        req.Method = WebRequestMethods.Ftp.DeleteFile; 
        if (nc != null) req.Credentials = nc; 
        if (cbSSL.Checked) req.EnableSsl = true; 
        req.Timeout = 10000; 

        res = (FtpWebResponse)req.GetResponse(); 
        res.Close(); 
    } 
    catch (WebException ex) 
    { 
        exists = false; 
    } 
    return exists; 
} 
0 голосов
/ 08 мая 2016

Единственным способом, который работал для меня, была обратная логика, пытаясь создать каталог / путь (который вызовет исключение, если он уже существует) и, если это так, затем удалите его снова. В противном случае используйте Исключение, чтобы установить флаг, указывающий, что каталог / путь существует. Я совсем новичок в VB.NET, и я уверен, что есть более хороший способ это написать, но в любом случае вот мой код:

        Public Function DirectoryExists(directory As String) As Boolean
        ' Reversed Logic to check if a Directory exists on FTP-Server by creating the Directory/Path
        ' which will throw an exception if the Directory already exists. Otherwise create and delete the Directory

        ' Adjust Paths
        Dim path As String
        If directory.Contains("/") Then
            path = AdjustDir(directory)     'ensure that path starts with a slash
        Else
            path = directory
        End If

        ' Set URI (formatted as ftp://host.xxx/path)

        Dim URI As String = Me.Hostname & path

        Dim response As FtpWebResponse

        Dim DirExists As Boolean = False
        Try
            Dim request As FtpWebRequest = DirectCast(WebRequest.Create(URI), FtpWebRequest)
            request.Credentials = Me.GetCredentials
            'Create Directory - if it exists WebException will be thrown
            request.Method = WebRequestMethods.Ftp.MakeDirectory

            'Delete Directory again - if above request did not throw an exception
            response = DirectCast(request.GetResponse(), FtpWebResponse)
            request = DirectCast(WebRequest.Create(URI), FtpWebRequest)
            request.Credentials = Me.GetCredentials
            request.Method = WebRequestMethods.Ftp.RemoveDirectory
            response = DirectCast(request.GetResponse(), FtpWebResponse)
            DirExists = False

        Catch ex As WebException
            DirExists = True
        End Try
        Return DirExists

    End Function

WebRequestMethods.Ftp.MakeDirectory и WebRequestMethods.Ftp.RemoveDirectory - методы, которые я использовал для этого. Все остальные решения у меня не сработали.

Надеюсь, это поможет

0 голосов
/ 24 сентября 2010

Я не смог заставить это предложение @BillyLogans работать ....

Я обнаружил, что проблема в том, что каталог FTP по умолчанию был / home / usr / fred

Когда я использовал:

String directory = "ftp://some.domain.com/mydirectory"
FtpWebRequest requestDir = (FtpWebRequest)FtpWebRequest.Create(new Uri(directory));

Я обнаружил, что это превращается в

"ftp:/some.domain.com/home/usr/fred/mydirectory"

чтобы остановить это, измените каталог Uri на:

String directory = "ftp://some.domain.com//mydirectory"

Тогда это начинает работать.

0 голосов
/ 05 мая 2010

Что бы это ни стоило, Вы значительно упростите свою жизнь на FTP, если будете использовать EnterpriseDT FTP .Это бесплатно и избавит вас от головной боли, потому что он имеет дело с командами и ответами.Вы просто работаете с хорошим, простым объектом.

0 голосов
/ 05 мая 2010

Перейдите в родительский каталог, выполните команду "ls" и проанализируйте результат.

...